c8051f020_AD转换程序
- 格式:doc
- 大小:32.50 KB
- 文档页数:5
C8051F同时实现AD和串口收发的程序//---------------------------------------------------------------------#include <C8051F020.h>#include "stdio.h"sfr16 TMR3RL = 0x92; //定时器3重装载寄存器sfr16 TMR3 = 0x94; //定时器3计数器sfr16 DP =0x82;sfr16 ADC0 =0xbe;sfr16 ADC0GT =0xc4;sfr16 ADCOLT =0xc6;sfr16 RCAP2 =0xca;sfr16 T2 =0xcc;sfr16 RCAP4 =0xe4;sfr16 T4 =0xf4;sfr16 DAC0 =0xd2;sfr16 DAC1 =0xd5;#define uchar unsigned char#define uint unsigned int//----------------------------------------------------------------------//参数设置区//----------------------------------------------------------------------#define BAUDRATE 9600 //波特率bps#define SYSCLK 11059200 //外部晶振,修改也要修改OSCXCN#define SMODV AL 0 //SMOD的值,修改请也修改PCONV AL#define PCONV AL 0x00 //PCON的值,=0x00时SMOD0=0; =0x80时SMOD0=1#define TXV AL (256-SYSCLK*(SMODVAL+1)/BAUDRA TE/384) //定时器初值#define MAX_LEN 1//每次接收/发送字符串的长度#define SAMPLERATE0 5000#define NUM_SAMPLES 1#define TURE 1#define FALSE 0//---------------------------------------------------------------------//全局变量//---------------------------------------------------------------------sbit LED = P1^6; //LED '1'亮'0'灭bit readFlag = 0; //读标志uchar readCounts = 0; //已经读取的字符个数,与MAX_LEN比较uchar idATa trdATa[MAX_LEN]; //要接收/发送的字符串xdA Ta unsigned samples[NUM_SAMPLES];bit ADC0_DONE;//----------------------------------------------------------------------//子函数声明//----------------------------------------------------------------------void SYSCLK_Init(void); //系统时钟初始化void PORT_Init(void); //端口初始化void UART0_Init(void); //串口UART0初始化void Send_Char(uchar ch); //发送单个字符void Send_String(uchar * str, uint len); //发送一个字符串void UART0_ISR(); //串口中断服务程序,接收字符void Timer3_Init(uint counts); //定时器3初始化void Timer3_ISR(void); //定时器3中断服务程序void ADC0_Init (void);//---------------------------------------------------------------------- //主函数//---------------------------------------------------------------------- void main(void){unsigned short i;floAT temp,k;WDTCN = 0xde; //禁止看门狗WDTCN = 0xad;P6&=0x02;here:i=0;SYSCLK_Init(); //时钟初始化PORT_Init(); //端口初始化UART0_Init(); //串口初始化Timer3_Init(SYSCLK/12/10); //定时器初始化EA = 1; //开全局中断ADC0_Init();AD0INT=0;AD0BUSY=1;while(AD0INT==0);temp=ADC0;k=(temp*2.4)/4096;printf("\n");printf("voltage%f",k);printf("\n");i=0;while(1){{if(readFlag) //已经读取{readFlag = 0; //清零Send_String(trdATa,MAX_LEN); //发送字符串i++;if(i==10000){goto here;}}}}}//----------------------------------------------------------------------//子函数具体实现//----------------------------------------------------------------------//系统时钟初始化void SYSCLK_Init(void){uint i;OSCXCN = 0x67; //采用外部晶振22.1184MHz,不分频. 选型OSCXCN=0110,0111 for(i=0;i<256;i++); //等待>1mswhile(!(OSCXCN&0x80)); //查询直到XTLVLD=1,晶振稳定OSCICN = 0x88; //切换到外部振荡器,允许时钟失效监测器. OSCICN=1000,1000 }//端口初始化void PORT_Init(void){XBR0 = 0x04; //允许UART0,RX,TX连到2个端口引脚. XBR0=0000,0100XBR1 = 0x00;XBR2 = 0x40; //交*开关使能P0MDOUT |= 0x03; //P0.0为推拉方式输出,即TX0,RX0所在的端口0000,0011P1MDOUT |=0x40; //P1.6为推拉方式输出,即LED所在的端口0100,0000}//串口初始化void UART0_Init(void){SCON0=0x50;TMOD=0x20;TH1=-(SYSCLK/BAUDRA TE/16);TR1=1;CKCON|=0x10;PCON|=0x80;TI0=1;TR0 = 1;ES0 =1; //UART0中断开启ADC时候要屏蔽TR1 = 1; //启动定时器T1}//定时器初始化void Timer3_Init(uint counts){TMR3CN = 0x00; //禁止定时器T3,清TF3,采用SYSCLK/12为时基TMR3RL = -counts; //初始化重装载值TMR3 = 0xffff; //设置为立即重装载EIE2 |= 0x01; //T3中断开启TMR3CN |= 0x04; //启动T3}//发送单个字符void Send_Char(uchar ch){SBUF0 = ch; //送入缓冲区1while(TI0 == 0); //等待发送完毕TI0 = 0; //软件清零}//发送字符串,调用Send_Char() len字符串长度void Send_String(uchar * str,uint len){uint k = 0;do{Send_Char(*(str + k));k++;} while(k < len);}//定时器3中断服务程序void Timer3_ISR(void) interrupt 14 using 0{TMR3CN &= ~(0x80); //清TF3LED = ~LED;}//UART0中断服务程序. 接收字符void UART0_ISR(void) interrupt 4 using 1{uchar rxch;if(RI0) //中断标志RI0=1 数据完整接收{RI0 = 0; //软件清零rxch = SBUF0; //读缓冲if(readCounts>=MAX_LEN){readCounts = 0;readFlag = 1;}trdATa[readCounts] = rxch; //存入数组,供发送readCounts++;}}//ADC0_Init//配置ADC0使用定时器3溢出作为转换启动信号,转换信号结束时候产生中断,使用左对齐输出方式//允许ADC0,但保持ADC0转换结束中断为禁止状态void ADC0_Init(void){ADC0CN=0x04; //定时器3 溢出启动ADC0 转换REF0CN=0x07; //内部偏压发生器工作,内部电压基准缓冲器工作。
C8051F320部有一个10位逐次逼近型ADC,可以工作在单端方式或者差分方式。
一、简要原理单片机集成了2个多路选择器,分别作为ADC的正输入信号和负输入。
正输入端由寄存器AMX0P控制输入信号,可以是P1~P3、温度传感器、VDD之一;负输入端由寄存器AMX0N控制输入信号,可以是P1~P3、VREF、GND之一。
单负输入端选择GND时,采用单端方式;其他情况则采用差分方式,即用正端相对于负端的电压进行转换。
*采用并行口作为输入信号时,必须将对应输入引脚设为模拟输入,并且对应的SKIP要设置为1,即跳过二、寄存器1、转换结果保存在两个8位寄存器ADC0H和ADC0L中,由于转换结果是10位,可以自由选择在寄存器中采用左对齐或者右对齐(下详)单端方式下,转换结果直接保存为10位的无符号数差分方式下,结果保存为10位有符号整数(原说明:2的补码。
未深究)2、温度传感器的输出电压由下面公式决定:V = 2.86(T)+ 776 (单位mv)从图表看,最高只能在1000mv左右,也就是10 0°时仅1V上下3、AD启动方式有六种启动方式,包括四个定时器溢出启动、特定位置1启动和P0.6上升沿启动。
(下详)采用中断时,中断号interrupt 104、跟踪方式对跟踪不是很理解!5、寄存器AMX0P,正输入通道选择寄存器00H~10H,对应P1.0~P3.0 0x1E对应温度传感器0x1F对应VDD 寄存器XMXON,负输入通道选择寄存器00H~10H,对应P1.0~P3.0 0x1E对应VREF 0x1F对应GND,此时为单端方式6、寄存器ADC0CF,配置寄存器,控制转换时钟,和数据保存方向D7~D3 时钟控制位,大意就是分频数,系统时钟与AD时钟的比值减1D2,为0时数据右对齐,为1时左对齐7、寄存器ADC0CN,控制寄存器。
D7,AD使能,0时禁止转换D6,跟踪方式,不懂D5,中断标志位,要手动清0D4,读取时为忙标志位,写入时可为启动标志位,但不知道要不要清0D3,窗口比较中断标志,不是很清楚D2~D0 转换方式选择,且受到D6影响。
240128的程序#include <c8051f020.h>#include <tab.c>#include <dis240128.c>////sfr16 DP = 0x82; // data pointersfr16 TMR3RL = 0x92; // Timer3 reload valuesfr16 TMR3 = 0x94; // Timer3 countersfr16 ADC0 = 0xbe; // ADC0 datasfr16 ADC0GT = 0xc4; // ADC0 greater than windowsfr16 ADC0LT = 0xc6; // ADC0 less than windowsfr16 RCAP2 = 0xca; // Timer2 capture/reloadsfr16 T2 = 0xcc; // Timer2sfr16 RCAP4 = 0xe4; // Timer4 capture/reloadsfr16 T4 = 0xf4; // Timer4sfr16 DAC0 = 0xd2; // DAC0 datasfr16 DAC1 = 0xd5; // DAC1 data//unsigned int ad_temp,dis_y=0;unsigned char ad_i=0;char tabc;unsigned char dis_i,dis_k=0;//unsigned char t_count,t_i;unsigned int t_timecount;bit t_flag;unsigned long t_y=0;//void SYSCLK_Init (void){unsigned int i; // delay counterOSCXCN = 0x67; // start external oscillator withfor (i=0; i < 3000; i++) ; // Wait for osc. to start upwhile (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settleOSCICN = 0x88;}//----------------------------------------------------------------------------- //函数名称: PORT_Init ()//函数功能: 通用I/O口及交叉开关初始化//入口参数: 无//出口参数: 无//全局变量引用: 无//调用模块: 无//-----------------------------------------------------------------------------void PORT_Init (void){XBR1 = 0x02;XBR2 = 0x40;P74OUT = 0x0f; // P2口设为推挽方式P4=0x07;}//void T_Init(void){CKCON=0X18;TMOD=0x15;IP=0x0a;TH0=0;TL0=0;TH1=(65536-44237)/256;TL1=(65536-44237)%256;TR1=1;TR0=1;ET0=1;ET1=1;}// ADC0配置,T3定时启动ADC//----------------------------------------------------------------------------- void ADC0_Init (void){ADC0CN = 0x00; // ADC0 向AD0BUSY写1时采样,左对齐REF0CN = 0x03; // 启用内部基准源ADC0CF =0X40;AMX0SL = 0x01;AD0EN =1; // 选择采样输入源EIE2 |= 0x02; // 启用 ADC 中断}//void t0(void) interrupt 1{t_count++;}void t1(void) interrupt 3{TH1=(65536-44237)/256;TL1=(65536-44237)%256;t_timecount++;if(t_timecount==250){TR0=0;t_timecount=0;t_flag=1;}}// ADC0采样中断//----------------------------------------------------------------------------- void ADC0_ISR (void) interrupt 15{AD0INT = 0; // 清 ADC 中断标志位ad_temp=((ADC0H*256+ADC0L)*13)>>10;tab_wave[ad_i]=(unsigned char)(ad_temp&0xff);ad_i++;if(ad_i>=216){ad_i=0;AD0EN=0;}AD0BUSY=1;}////----------------------------------------------------------------------------- // 主程序//----------------------------------------------------------------------------- void main (void){WDTCN = 0xde;WDTCN = 0xad; //禁止看门狗定时器SYSCLK_Init (); // 系统时钟初始化PORT_Init ();ADC0_Init ();T_Init();lcd_int1();wtcd2(0x24,0x0000);show_coor(X_length,Y_length,origin_X,origin_Y,0,0);showxy();displayword(0,112,tab_word,2);displayword(13,112,tab_word+64,2);displaychar(6,112,tab_char+48,1);displaychar(10,112,tab_char+64,1);displaychar(23,112,tab_char+80,2);AD0BUSY=1;EA = 1;while(1){//幅度显示if(AD0EN==0){show_wave(1);for(dis_i=0,dis_k=0;dis_i<216;dis_i++)if(tab_wave[dis_i]>dis_k)dis_k=tab_wave[dis_i];dis_y=(unsigned int)dis_k;dis_y=(dis_y*755)>>4;//dis_y=dis_y>>8;displaychar(5,112,tab_number+(dis_y/1000%10)*16,1); displaychar(7,112,tab_number+(dis_y/100%10)*16,1); displaychar(8,112,tab_number+(dis_y/10%10)*16,1); displaychar(9,112,tab_number+(dis_y%10)*16,1);////计数显示for(t_i=0;t_i<6;t_i++){if(t_flag==1){t_flag=0;t_y=(t_count*65536+TH0*256+TL0)*2;t_timecount=0;t_count=0;TH0=0;TL0=0;TR0=1;}displaychar(18,112,tab_number+(t_y/10000%10)*16,1); displaychar(19,112,tab_number+(t_y/1000%10)*16,1); displaychar(20,112,tab_number+(t_y/100%10)*16,1); displaychar(21,112,tab_number+(t_y/10%10)*16,1);displaychar(22,112,tab_number+(t_y%10)*16,1);}//show_wave(0);show_coor(X_length,Y_length,origin_X,origin_Y,0,0);showxy();AD0EN=1;AD0BUSY=1;}}}---------------------------------------------------------------------------------------------------------------dis240128.c文件--------------------------------------------------------------------------------------------------------------#define X_length 216 //x way#define Y_length 106 //y way#define origin_X 0 //原点x(绝对坐标)#define origin_Y 53 //原点y(绝对坐标)y为53//unsigned char cklcdst(void){unsigned char temp;P5 = 0xFF;P4 = 0x03;temp=P5;P4=0x07;return temp;}//void check01(void) // 状态位STA1,STA0 判断(读写指令和读写数据){while(cklcdst()&0x03!=0x03);}///*void check3(void) // 状态位ST3 判断(数据自动写状态){while(cklcdst()&0x08!=0x08);//void check2(void) // 状态位ST2 判断(数据自动读状态){while(cklcdst()&0x04!=0x04);}//void check6(void) // 状态位ST6 判断(屏读/屏拷贝状态){while(cklcdst()&0x40!=0x40);}//void delay1000(unsigned char delayvalue){unsigned char i;unsigned int j;i = delayvalue;while(i--){j = 1000;while(j--);}}//void awtdt0(unsigned char uData) // 自动写数据{check3();wtdt(uData);}*///void delay50(unsigned char delayvalue){unsigned char i,j;i = delayvalue;while(i--){j = 50;while(j--);}void wtcd(unsigned char cmd){P4=0x05;P5=cmd;P4=0x07;delay50(1);}//------------------------------------------------------------------------------ // IO口方式写数据//------------------------------------------------------------------------------ // status: O.K.void wtdt(unsigned char lcddata){P4=0x04;P5=lcddata;P4=0x06;delay50(1);}//void wtcd2(unsigned char uCmd,unsigned int uPar) // 写双参数的指令{check01();wtdt(uPar& 0xFF);//先写低字节,再写高字节check01();wtdt((unsigned char)(uPar>>8));check01();wtcd(uCmd);}/********************//= 函数原型: uchar wr_cmd_1(uchar uCmd,uchar uPar1)//= 功能: 给T6963C写带单参数的指令//= 参数://= 返回值: 返回0 成功,否则忙//= 函数性质:私有函数********************/void wtcd1(unsigned char uCmd,unsigned char uPar) // 写单参数的指令{check01();wtdt(uPar);check01();wtcd(uCmd);}void wtcd0(unsigned char uCmd) // 写无参数的指令{check01();wtcd(uCmd);}//void wtdt0(unsigned char uData) // 写一次数据{check01();wtdt(uData);}//void lcdclr( ){ unsigned char i,j;wtcd2(0x24,0x0000);wtcd0(0xb0);for(j=0;j<=0x80;j++)for(i=0;i<=0x1E;i++)wtdt0(0x00);wtcd0(0xb2);}//---------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- //初始化函数void lcd_int1( ){ lcdclr(); //清屏wtcd2(0x42,0x0000);wtcd2(0x43,0x001e); //图形显示宽度30wtcd2(0x24,0x0000);wtcd0(0x80); //显示方式 OR功能wtcd0(0x98); //启用图形显示方式,光标闪烁}//void printpoint(unsigned char PointX,unsigned char PointY,bit flag){unsigned int k=0;unsigned char ldata=0xf0;//bit operation : flag=0 bit reset and flag=1 bit set;(7-PointY%8)is select bit.k=PointY*30 + PointX/8; //k save the addressldata=ldata+7-PointX%8;if(flag)ldata=ldata|0x08;wtcd2(0x24,k);wtcd0(ldata); //output the bit operation}//--------------------------------------------------------------------------void show_coor(unsigned char x_length,unsigned char y_length,unsigned char origin_x, unsigned char origin_y,bit offset,bit offset1){unsigned char i,j,k,l,m;//show coordinate start pointif((offset==0)&&(offset1==0)){ j=origin_x;k=x_length+origin_x+6;l=origin_y-y_length/2;m=y_length+origin_y-y_length/2+3; //y way length}else if((offset==0)&&(offset1==1)){j=origin_x;k=x_length+origin_x+6;l=origin_y;m=y_length+origin_y+3;}else if((offset==1)&&(offset1==0)){j=origin_x;k=x_length+origin_x+6;l=origin_y-y_length;m=y_length+origin_y-y_length+3;}//show the coordinatefor(i=j;i<k;i++)//x wayprintpoint(i,origin_y,1);for(i=l;i<m;i++)//Y_wayprintpoint(origin_x,i,1);for(i=l;i<m;i=i+y_length/8) //y_way average dividing{printpoint(origin_x+1,i,1);}for(i=j;i<k;i=i+x_length/8)//x way average dividing{ printpoint(i,origin_y-1,1);}printpoint(i-1,origin_y-1,1);//x way the next point}//----------------------------------------------------------------------------------void show_wave(bit mod)// y 0 1{ unsigned char i,k;for(i=1;i<X_length;i++){k=origin_Y-tab_wave[i];if(k!=origin_Y)printpoint(origin_X+i,k,mod);}}//汉化显示程序,y为行,x为列,注意一个汉字占两列,而西文字符占一列void displayword(unsigned char x,unsigned char y,unsigned char *word,unsigned char c){unsigned int xy;unsigned char i,j,k=0;xy=y*30+x;for(i=0;i<c;i++)for(j=0;j<16;j++){wtcd2(0x24,xy+j*30+i*2);//置地址指针 low addresswtcd1(0xc0,word[k]);wtcd1(0xc0,word[k+1]);k+=2;}}//字符显示程序,y为行,x为列,注意一个汉字占两列,而西文字符占一列void displaychar(unsigned char x,unsigned char y,unsigned char *word,unsigned char c){unsigned int xy;unsigned char i,j,k=0;xy=y*30+x;for(i=0;i<c;i++)for(j=0;j<16;j++){wtcd2(0x24,xy+j*30+i);//置地址指针 low addresswtcd1(0xc0,word[k]);k++;}}void showxy(void){displaychar(1,0,tab_char,1);displaychar(27,54,tab_char+16,1);displaychar(1,54,tab_char+32,1);}--------------------------------------------------------------------------------------------------------------tab.c文件--------------------------------------------------------------------------------------------------------------unsigned char code tab_number[]={/*-- 文字: 0 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*-- 文字: 1 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*-- 文字: 2 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,/*-- 文字: 3 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*-- 文字: 4 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,/*-- 文字: 5 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*-- 文字: 6 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*-- 文字: 7 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,/*-- 文字: 8 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/*-- 文字: 9 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,};unsigned char code tab_char[]={/*-- 文字: y --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x18,0x10,0x10,0xE0,0x00,0x00,0x00,0x00, /*-- 文字: x --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00,0x00,0x00,0x00,0x00, /*-- 文字: 0 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00, /*-- 文字: . --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, /*-- 文字: V --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00, /*-- 文字: H --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*-- 文字: z --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x08,0x10,0x10,0x22,0x7E,0x00,0x00, };//unsigned char code tab_word[]={/*-- 文字: 幅 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x00,0x23,0xFE,0x20,0x00,0xF9,0xFC,0xA9,0x04,0xA9,0x04,0xA9,0xFC,0xA8,0x00, 0xAB,0xFE,0xAA,0x22,0xAB,0xFE,0xBA,0x22,0x22,0x22,0x23,0xFE,0x22,0x02,0x20,0x00,/*-- 文字: 度 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x2F,0xFC,0x22,0x20,0x23,0xE0, 0x20,0x00,0x27,0xF8,0x22,0x10,0x21,0x20,0x20,0xC0,0x41,0x30,0x46,0x0E,0x98,0x04,/*-- 文字: 频 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x00,0x08,0xFE,0x4E,0x20,0x48,0x40,0x48,0xFC,0xFE,0x84,0x00,0xA4,0x08,0xA4, 0x4A,0xA4,0x4A,0xA4,0x84,0xA4,0x08,0x50,0x10,0x48,0x20,0x86,0xC3,0x02,0x00,0x00,/*-- 文字: 率 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x02,0x00,0x01,0x00,0x7F,0xFE,0x41,0x00,0x22,0x28,0x17,0xD0,0x04,0x80,0x11,0x10, 0x22,0x48,0x47,0xC4,0x01,0x20,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,};//unsigned char tab_wave[216];。
C8051F020单片机初始化程序和编译步骤2011-02-15 12:20:06| 分类:默认分类| 标签:|字号大中小订阅C8051F020编程步骤一、编程步骤:1、看门狗设置2、系统初始化3、端口初始化4、对应功能初始化(如:串口,定时器,I2C,SPI,PCA,DAC/ADC,中断等等)5、功能函数或中断函数(如需要)6、包含的头文件7、项目说明二、对应功能初始化要点:1、Uart:(1)串口工作模式由SCON设定(2)定时器工作方式设定TMOD (3)波特率TH载入值设定(4)启动TR1 (5)时钟基准CKCON (6)波特率加倍设定PCON(7)开中断使能TI2、Time:(1)工作方式设定TMOD (2)定时器时钟基准CKCON (3)启动/停止TCON设定TRn3、Interrupt:(1)中断允许IE (2)触发方式设定(上下沿,电平)(3)对应控制位允许设定,如ES串口允许C8051F020单片机初始化程序; $INCLUDE (C8051F020.inc) /C8051F020单片机功能强大,初始化也比较繁杂,为了便于初始化各功能模块,我们编了此程序可看着“说明”初始化。
ORG SYS_INIT;※▲◆●◎★☆△;◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆;■-- <1> --电源管理; PCON ; POWER CONTROL;■-- <2> --系统时钟和振荡器; OSCXCN ; EXTERNAL OSCILLATOR CONTROL; OSCICN ; INTERNAL OSCILLA TOR CONTROL;■-- <3> --复位及看门狗管理; RSTSRC ; RESET SOURCE; WDTCN ; WA TCHDOG TIMER CONTROL;■-- <4> --FLASH存储器编程和安全管理; FLSCL ; FLASH MEMORY TIMING PRESCALER; PSCTL ; PROGRAM STORE R/W CONTROL; FLACL ; FLASH ACESS LIMIT;■-- <5> --中断控制; IE ; INTERRUPT ENABLE; EIE1 ; EXTERNAL INTERRUPT ENABLE 1; EIE2 ; EXTERNAL INTERRUPT ENABLE 2; IP ; INTERRUPT PRIORITY; EIP1 ; EXTERNAL INTERRUPT PRIORITY REGISTER 1; EIP2 ; EXTERNAL INTERRUPT PRIORITY REGISTER 2 ; P3IF ; PORT 3 EXTERNAL INTERRUPT FLAGS;■-- <6> --端口IO初始化及交叉开关设置; XBR0 ; DIGITAL CROSSBAR CONFIGURA TION REGISTER 0; XBR1 ; DIGITAL CROSSBAR CONFIGURA TION REGISTER 1; XBR2 ; DIGITAL CROSSBAR CONFIGURA TION REGISTER 2 ; P0MDOUT ; PORT 0 OUTPUT MODE CONFIGURATION; P1MDOUT ; PORT 1 OUTPUT MODE CONFIGURATION; P2MDOUT ; PORT 2 OUTPUT MODE CONFIGURATION; P3MDOUT ; PORT 3 OUTPUT MODE CONFIGURATION; P74OUT ; PORTS 4 - 7 OUTPUT MODE;■-- <7> --外部RAM和片内XRAM; EMI0CN ; EXTERNAL MEMORY INTERFACE CONTROL; EMI0CF ; EXTERNAL MEMORY INTERFACE (EMIF) CONFIGURA TION; EMI0TC ; EXTERNAL MEMORY;■-- <8> --定时器设置; TMOD ; TIMER MODE; TCON ; TIMER CONTROL; T2CON ; TIMER 2 CONTROL; T4CON ; TIMER 4 CONTROL; TMR3CN ; TIMER 3 CONTROL; TMR3RLL ; TIMER 3 RELOAD REGISTER - LOW BYTE; TMR3RLH ; TIMER 3 RELOAD REGISTER - HIGH BYTE; TMR3L ; TIMER 3 - LOW BYTE; TMR3H ; TIMER 3 - HIGH BYTE;■-- <9> --串行通讯; SCON0 ; SERIAL PORT 0 CONTROL; SCON1 ; SERIAL PORT 1 CONTROL; SBUF1 ; SERAIL PORT 1 DA TA; SADDR1 ; SERAIL PORT 1; PCON ; POWER CONTROL; RCAP2L ; TIMER 2 CAPTURE REGISTER - LOW BYTE; RCAP2H ; TIMER 2 CAPTURE REGISTER - HIGH BYTE; RCAP4L ; TIMER 4 CAPTURE REGISTER - LOW BYTE; RCAP4H ; TIMER 4 CAPTURE REGISTER - HIGH BYTE; SADDR0 ; SERIAL PORT 0 SLAVE ADDRESS;■-- <10> --可编程计数器阵列; PCA0CN ; PCA 0 COUNTER CONTROL; PCA0MD ; PCA 0 COUNTER MODE; PCA0CPM0 ; CONTROL REGISTER FOR PCA 0 MODULE 0; PCA0CPM1 ; CONTROL REGISTER FOR PCA 0 MODULE 1; PCA0CPM2 ; CONTROL REGISTER FOR PCA 0 MODULE 2; PCA0CPM3 ; CONTROL REGISTER FOR PCA 0 MODULE 3; PCA0CPM4 ; CONTROL REGISTER FOR PCA 0 MODULE 4;■-- <11> --SMBus通讯; SMB0CN ; SMBUS 0 CONTROL; SMB0CR ; SMBUS 0 CLOCK RA TE; SMB0STA; SMBUS 0 STA TUS; SMB0DA T ; SMBUS 0 DATA; SMB0ADR ; SMBUS 0 SLAVE ADDRESS;■-- <12> --SPI总线通讯; SPI0CKR ; SERIAL PERIPHERAL INTERFACE 0 CLOCK RA TE CONTROL ; SPI0DAT ; SERIAL PERIPHERAL INTERFACE 0 DA TA ; SPI0CFG ; SERIAL PERIPHERAL INTERFACE 0 CONFIGURATION ; SPI0CN ; SERIAL PERIPHERAL INTERFACE 0 CONTROL;-- <13> --ADC转换; AMX0CF ; ADC 0 MUX CONFIGURATION; AMX0SL ; ADC 0 MUX CHANNEL SELECTION; ADC0CF ; ADC 0 CONFIGURA TION; ADC0CN ; ADC 0 CONTROL; ADC0L ; ADC 0 DA TA - LOW BYTE; ADC0H ; ADC 0 DATA - HIGH BYTE; ADC1CF ; ADC 1 ANALOG MUX CONFIGURATION; AMX1SL ; ADC 1 ANALOG MUX CHANNEL SELECT; ADC1CN ; ADC 1 CONTROL; ADC0GTL ; ADC 0 GREA TER-THAN REGISTER - LOW BYTE; ADC0GTH ; ADC 0 GREA TER-THAN REGISTER - HIGH BYTE ; ADC0LTL ; ADC 0 LESS-THAN REGISTER - LOW BYTE; ADC0LTH ; ADC 0 LESS-THAN REGISTER - HIGH BYTE; REF0CN ; VOLTAGE REFERENCE 0 CONTROL; ADC1 ; ADC 1 DA TA;■-- <14> --DAC转换; PCA0L ; PCA 0 TIMER - LOW BYTE; PCA0H ; PCA 0 TIMER - HIGH BYTE; DAC0CN ; DAC 0 CONTROL; DAC1L ; DAC 1 REGISTER - LOW BYTE; DAC1H ; DAC 1 REGISTER - HIGH BYTE; DAC1CN ; DAC 1 CONTROL;■-- <15> --比较器设置; CPT0CN ; COMPARA TOR 0 CONTROL; CPT1CN ; COMPARA TOR 1 CONTROL; EMI0TC ; EMIF TIMING CONTROL;■-- <16> --时钟/电压基准设置; CKCON ; CLOCK CONTROL; SADEN1 ; SERIAL PORT 1 SLAVE ADDRESS MASK; SADEN0 ; SERIAL PORT 0 SLAVE ADDRESS MASK; P1MDIN ; PORT 1 INPUT MODE; PSW ; PROGRAM STATUS WORD; B ; B REGISTER; WDTCN ; WA TCHDOG TIMER CONTROL;◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆;;==================================================================== ; function: Init_CTS 定时器/计数器,中断和串行通讯初始化子程序; input: -----------------; output: -----------------; usage: -----------------;====================================================================THS0 equ 0a8hTLS0 equ 09ah; THS1 equ 0fah;0feh;0fah;-4800;0f4h; TLS1 equ 0fah;0feh;0fah;-4800;0f4h;; THS2 equ 0ffh;0feh;0fah;-4800;0f4h; TLS2 equ 0b8h;0feh;0fah;-4800;0f4hInit_TCS: ;定时器/计数器,中断和串行通讯初始化子程序;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓; ◆◆◆8051内部控制寄存器◆◆◆;************************************************************************************ ;|名称| 代号| 地址|位寻| B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | ;|--------|------|------|----|-----|------|------|------|------|------|------|------| ;|电源控制| PCON | 87H | NO |SMOD | -- | -- | -- | GF1 | GF0 | PD | IDL | ;|--------|------|------|----|-----|------|------|------|------|------|------|------| ;|计时控制| TCON | 88H | YE |TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 | ;|--------|------|------|----|-----|------|------|------|------|------|------|------|;|计时模式| TMOD | 89H | NO |1GATE| 1C/T | 1M1 | 1M0 | 0GA TE| 0C/T | 0M1 | 0M0 | ;|--------|------|------|----|-----|------|------|------|------|------|------|------|;|串行控制| SCON | 98H | YE |SM0| SM1 | SM2 | REN | TB8 | RB8 | TI | RI | ;|--------|------|------|----|-----|------|------|------|------|------|------|------|;|中断允许| IE | A8H | YE |EA| -- | ET2 | ES | ET1 | EX1 | ET0 | EX0 | ;|--------|------|------|----|-----|------|------|------|------|------|------|------| ;|中断优先| IP | B8H | YE |-- | -- | PT2 | PS | PT1 | PX1 | PT0 | PX0 | ;************************************************************************************;时钟频率为:11.059200MHz;;机器周期为:12/fosc=1.085069μs;;CT0定时器设定延时为:2000μs;;CT0定时器工作于模式0;;CT0溢出处理采用中断方式;;CT0选择内部时钟;;CT0启动由TR0的0/1决定;;设定波特率为:4800bps;;串口0工作于方式1--T1定时器工作于方式2;;串口1工作于模式3--T2定时器用于波特率发生器4800bpsmov TH0, #THS0mov TL0, #TLS0; mov TH1, #THS1; mov TL1, #TLS1; mov TH2, #THS2; mov TL2, #TLS2;▲■-- <1> --电源管理;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓;87H---PCON-------电源控制寄存器;复位值: 00000000;位7-2:保留。
AD转换c 语言程序#include "c8051f020.h"#include<absacc.h>#include<intrins.h>#define ad0809 XBYTE[0x2f80] //A/D地址/********函数声明********/void Send7279Byte(unsigned char ch); //发送一个命令字void Delay1us(unsigned char us) ; //延时1μvoid Delay1ms(unsigned char T) ; //延时1msvoid delay10ms(unsigned char time);void SYSCLK_Init (void);//**** 变量及I/O口定义*********unsigned char adx1,adx10,adx100,m,n;unsigned char n31=4,n01,sure,k,mm;unsigned int set,tmr, he;sbit CLK = P1^6; // HD7279sbit DAT = P1^7; // HD7279#define NOSELECT7279 P5 |= 0x80 //SPICS4(P57)=1 #define SELECT7279 P5 &= ~(0x80) //SPICS4(P57)=0//***********延时N * 1μ*****************************//void Delay1us(unsigned char us) //延时1μ{while (us){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();--us;}}//*********发送一个命令字****************//void Send7279Byte(unsigned char ch) //发送一个命令字{char i;SELECT7279; //置CS低电平Delay1us(100); //延时50μfor (i=0;i<0x8;i++){if (ch&0x80) //输出7位到HD7279A的DATA端{DAT=1;}else{DAT=0;}CLK=1; //置CLK高电平ch=ch<<1; //待发数据左移Delay1us(20); //延时8μCLK=0; //置CLK低电平Delay1us(20); //延时50μ}DAT=0; //发送完毕,DATA端置低,返回}/************* 显示时钟************/void displaytime() //显示时钟{Send7279Byte(0xcd) ;Send7279Byte(0xa) ; ////显示“A”Send7279Byte(0xcc) ;Send7279Byte(0xd) ; // //显示“D”Send7279Byte(0x83) ;Send7279Byte(0xa) ; // //显示“-”Send7279Byte(0x82) ;Send7279Byte( adx100) ; //显示百位Send7279Byte(0x81) ;Send7279Byte( adx10); //显示十位Send7279Byte(0x80);Send7279Byte(adx1); //显示个位}//*********单片机时钟初始化***********//void SYSCLK_Init (void){int i; // delay counterOSCXCN = 0x65; // start external oscillator with// 18.432MHz crystal for (i=0; i < 256; i++) ; // Wait for osc. to start upwhile (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settleOSCICN = 0x88; // select external oscillator as SYSCLK// source and enable missing clock// detector}//***************//初始化IO口*************************//void PORT_Init (void){//XBR0 = 0x07; // Enable SMBus, SPI0, and UART0XBR1= 0x02; //交叉开关允许XBR2 = 0x40; // Enable crossbar and weak pull-upsEMI0CF=0x2F ; //复用方式,高4端口。
51单片机ad转换流程51单片机是一种广泛应用于嵌入式系统中的微控制器。
与其他单片机相比,51单片机的特点之一是其模拟到数字转换功能(AD转换),它允许将模拟信号转换为数字量,以便进行数字信号处理和控制。
在本文中,我们将以“51单片机AD转换流程”为主题,详细介绍AD转换的步骤和相关概念。
第一步:了解AD转换的基本概念模拟到数字转换(AD转换)是电子系统中一种常见的操作。
它涉及将连续的模拟信号转换为离散的数字信号,以便进行数字信号处理。
AD转换的结果通常以二进制形式表示,可以被计算机或其他数字处理设备使用。
在AD转换过程中,最重要的参数是分辨率和采样率。
分辨率是指AD转换器能够分辨的最小信号变化量,通常以比特数表示。
例如,8位AD转换器的分辨率为2^8,即256个离散的信号水平。
采样率是指AD转换器每秒钟进行的样本数量,通常以赫兹(Hz)表示。
第二步:准备硬件连接在进行AD转换之前,需要连接电源、待转换的模拟信号源和51单片机上的AD输入引脚。
具体的硬件连接方式可以根据具体的应用需求和开发板设计进行调整。
通常情况下,待转换的模拟信号将通过电阻网络与AD输入引脚相连接。
这个电阻网络起到电压分压的作用,将输入信号的幅度限制在AD转换器可接受的范围内。
开发板上的AD输入引脚通常还具有可选的电容网络,用于去除输入信号中的高频噪声。
第三步:配置AD转换器参数在开始AD转换之前,需要通过编程设置51单片机上的AD转换器参数。
这些参数包括分辨率、输入通道选择、参考电压选择和采样率等。
这些参数的设置是通过对寄存器的操作来实现的。
通过写入相应的寄存器值,我们可以选择转换的分辨率。
51单片机上的AD转换器可以支持不同的分辨率,如8位、10位或12位。
选择转换的输入通道也是一个重要的步骤。
通常情况下,AD转换器具有多个输入信道,可以同时转换多个信号。
需要根据具体的信号源,选择合适的输入通道。
参考电压的选择也要根据具体的应用需求来确定。
C8051F020开发板说明书V1.0.02012年3月22日目录第一章 概述 (1)第二章 开发板简介 (2)2.1 开发板原理框图 (2)2.2 开发板实物图 (2)2.2.1 本开发板的外扩展资源和扩展接口 (2)2.2.2 本开发板的平面图 (3)第三章 开发板硬件电路说明 (4)3.1 硬件电路简介 (4)3.2 电源电路 (4)3.3单片机复位电路 (4)3.4 ZLG7289电路原理图 (5)3.5 LED电路原理图 (6)3.6 LCD接口电路 (7)第四章 开发板注意事项 (8)4.1注意事项 (8)4.2开发板跳线使用方法 (8)第一章 概述本说明书是C8051F020开发板的硬件使用说明书,详细描述了020开发板的硬件构成、原理,以及它的使用方法。
开发板用USB JTAG对C8051F020芯片进行编程,C8051F020有64个I/O而我们开发板通过排针引出了其中的44个I/O口,板上有标识(也可查看原理图或PCB图)。
引出来的I/O口可以供用户配置。
第二章 开发板简介2.1 开发板原理框图本开发板主要用到了C8051F020芯片(内置A/D D/A和比较器等)和周立功的ZLG7289芯片,020芯片通过SPI方式和ZLG7289完成数据传递,ZLG7289控制按键和数码管显示。
原理框图如下:图2-1 开发板原理框图2.2 开发板实物图2.2.1 本开发板的外扩展资源和扩展接口部分接口说明:JTAG接口:本板卡和USB Debug Adaptor仿真器连接,通过本接口用户可实现在线仿真。
LCD接口: 本板液晶用MzL05-12864AD/DA接口:本板的AD/DA接口都来自020内置的AD/DA另外的外扩资源和接口如下图所示:数码管AD 接口比较器接口P7口P3.0~ P3.6P0口P2口P1口3.2 JTAG3.3V/GNDDAC 接口LCD 接口LED ZLG72895vGNDP6口C8051F0203.3V/GND 按键电源开关复位键开发板实物图2.2.2 本开发板的平面图平面图上的位置和板卡的位置一一对应,详细的说明请看后面章节的图2-2 说明。
基于C8051F020单片机的16位A/D转换器设计1 引言本文给出了基于C8051F020单片机的16位A/D转换器设计思路及实现方法。
在设计中,充分利用了C8051F020单片机内部的高速计数器,本文给出的设计与常规的双积分ADC相比,具有转换速率高、可对双极性模拟电压进行转换等显著优点,且实现简单,运行稳定可靠。
2 A/D转换器硬件电路图1为A/D转换硬件电路。
图中,LM336为5V电压基准源,CD4052为2路四选一电子开关。
在正常转换过程中,Vin输入端的开关RY断开,输入待测电压信号(-5V~+5V),此信号经过运放OP07-1构成的电压跟随器后,输入到运放OP07-2的反相输入端,加入电压跟随器的目的是进行阻抗变换。
运放OP07-2构成加法器,其输出为:V OI=-(V I+V CP) (1)VCP为补偿电压,将双极性输入电压VI转换成单极性电压VO1,以实现与偏移二进制码对应的A/D转换,其值为输入电压VI的上限值。
若输入电压VI 取值范围为:-5V<VI<5V,则VCP=5V。
输出电压VO1的取值范围为-10V<VO1<0V。
3 A/D转换器程序流程及工作原理图2为A/D转换过程程序流程图:A/D转换开始前先将计数器清零。
在软件控制下,选通CD4052的2Y管脚,构成放电回路使积分电容C完全放电,然后开始A/D转换,转换操作分两步进行:第一步,选通CD4052的0X管脚,积分器对VO1进行固定时间T1的积分,积分结束时积分器的输出电压VO2为:(2)第二步,选通CD4052的1X管脚,积分器对参考电压VREF向相反方向积分,若积分器的输出电压到零时所经过的积分时间为T2,则有:(3)故得到:(4)上述三式中VREF为A/D 转换器的基准电压,由C8051F020片内的12位D/A转换器DAC0提供。
可见,T2与进行固定时间间隔积分的电压信号VO1成正比,令计数器在这段时间里对固定频率为fc (fc=1/TC)的时钟脉冲计数,计数值即为转换成的数字量,即(5)式中D为表示计数结果的数字量,即A/D转换值。
AD转换的步骤
A/D转换的步骤:
1.端口的配置,需要单片机外部采样时,把端口配置成输入模式,有TRIS 和 ANSEL设定;
2.配置A/D模块:
(1)选择A/D转换时钟;
(2)配置参考电压;
(3)选择A/D输入通道;
(4)配置A/D转换结果存储的格式;
(5)做好以上几步后,选择就可以启动A/D转换模块了;
3.配置ADC 中断;
(1)清零ADC 中断标志位;
(2) 允许ADC 中断;
(3) 允许外设中断;
(4) 允许全局中断;
4.等待所需的采集时间;
5.将GO/DONE 置1 启动转;
6.由如下方法之一等待ADC 转换结束;
(1)查询GO/DONE 位;
(2) 等待ADC 中断(允许中断);
7.读ADC 结果;
8.将ADC 中断标志位清零(如果允许中断的话,需要进行此操作);。
C8051F020(简称F020)是美国德州Cygnal公司推出的一种混合信号SOC型8位单片机。
它属于C8051F系列中的F02X子系列。
其性能价格比在目前应用领域极具竞争力。
F020具有8路12位A/D转换(简称ADC)接口和8路8位在线可编程(ISP)的ADC 电路,片上的特殊功能寄存器(简称SFR)有15个与ADC的控制相关,它们是:AMUX0SL-AMUX0通道选择寄存器,复位值为00000000;AMX0CF-AMUX0配置寄存器,复位值为00000000;ADC0CF-ADC0配置寄存器,复位值为11111000;ADC0CN-ADC0控制寄存器,复位值为00000000;ADC0H-ADC0数据字MSB寄存器,复位值为00000000;ADC0L-ADC0数据字LSB寄存器,复位值为00000000;ADC0GTH-ADC0下限数据高字节寄存器,复位值为11111111;ADC0GTL-ADC0下限数据低字节寄存器,复位值为11111111;ADC0LTH-ADC0上限数据高字节寄存器,复位值为00000000;ADC0LTL-ADC0上限数据低字节寄存器,复位值为00000000;AMX1SL-AMUX1通道选择寄存器,复位值为00000000;ADC1CN-ADC1控制寄存器,复位值为00000000;ADC1CF-ADC1配置寄存器,复位值为11111000;ADC1-ADC1数据字寄存器,复位值为00000000;REF0CN-基准电压控制寄存器,复位值为00000000;ADC是混合信号控制器的重要功能,如欲在应用编程中得心应手,就必须对其相关的要素有较清晰的整体认识。
1、ADC的精度与通道F020采用TQFP100封装,芯片引脚有8个(引脚18-25)专用于模拟输入,是8路12位ADC的输入端。
每路12位的转换精度都是其自身的±1LSB(最低位)。
实际上,对应12位逐次逼近寄存器型(SAR)ADC只有1个,在它与各输入端之间有1个具有9 通道输入的多路选择开关(可配置模拟多路开关AMUX)。
此程序设置ADc0的0通道转换模拟量具体程序如下:////////////////////////////////////// Generated Initialization File ///////////////////////////////////////#include "C8051F020.h"unsigned char temp_H,temp_L; //用来观察ADC0H,及ADC0L的值// Peripheral specific initialization functions,// Called from the Init_Device() functionvoid Timer_Init(){TMR3RLL = 0xD2; //设置重装值TMR3RLH = 0x04;TMR3L = 0xFF;//设置初值TMR3H = 0xFF;}void ADC_Init(){ADC0CN = 0x84; //使能ADC0,定时器3溢出转换ADC0CF=0X50; //设定转换周期5,设定增益为1//AMX0CF=0X00; //自己设置两个寄存器是自己设置初始化应该就是0x00//AMX0SL=0X00; // 不用设置??}void Voltage_Reference_Init(){REF0CN = 0x03;}void Oscillator_Init(){int i = 0;OSCXCN = 0x67;for (i = 0; i < 3000; i++); // Wait 1ms for initializationwhile ((OSCXCN & 0x80) == 0);OSCICN = 0x0C;}void Interrupts_Init(){IE = 0x80; //使能总中断EIE2 = 0x02; //允许ADC0转换结束中断}// Initialization function for device,// Call Init_Device() from your main programvoid Init_Device(void){Timer_Init();ADC_Init();Voltage_Reference_Init();Oscillator_Init();Interrupts_Init();}void delay_ms(unsigned int t){ unsigned char i=0;while(t--)for(i=0;i<150;i++);}//void main(){WDTCN=0XDE;WDTCN=0XAD;Init_Device();TMR3CN|=0X04;//TR3=1; while(1){delay_ms(5);}}void ADC_interr()interrupt 15 {AD0INT=0;TMR3CN&=0XFB;//关定时器3temp_H=ADC0H;temp_L=ADC0L;TMR3CN|=0X04;//TR3=1;}//在KEIL仿真时,定时器3溢出第一次时溢出标志位TF3=1;在程序中没有将其清零的语句,在以后执行程序时TF3一直为1//但是不影响AD转换,在实验中只要定时器溢出一次就转换一次在KEIL仿真如下:第一步:编写完程序后编译无错误按Ctrl+F5进入KEIL仿真第二步:设置断点如图,在菜单栏的Peripherils点击timer中的timer3 及ADC0,操作后仿真界面如下:然后在右下角选择WATCH1,按F2设置观察变量temp_H,temp_L第三步:在anolog/digital converter设置0通道的转换值第四步:进行单步或全速仿真;观察timer3和anolog/digital converter窗口的值的变化。
C8051F的每个I/O口引脚都可以被配置为推挽或漏极开路输出。
同时引入了数字交叉开关,允许将内部数字系统资源映射到P0、P1、P2和P3 的端口引脚。
通过设置交叉开关寄存器可将片内的计数器/定时器、串行总线、硬件中断、ADC转换启动输入、比较器输出以及微控制器内部的其他数字信号配置为出现在端口I/O引脚。
必须在访问这些外设的I/O之前配置和允许交叉开关。
注意的问题:1.低端口既能按位寻址,也可以按字节寻址;高端口只能按字节寻址。
2.没有被分配到的引脚作为一般的数字通用I/O口。
3.P1口还可以用作ADC1的模拟输入。
4.P0MDOUT~P3MDOUT用于控制I/O端口每一位的输出状态。
5.EMIF(外部存储器接口)是用于CPU与片外XRAM之间的数据传输通道,通过寄存器EMI0CF 和EMI0CN选择和管理端口实现数据的传输。
6.为了能访问片外存储器空间,必须设置EMI0CN寄存器的内容为片外存储器的空间页地址。
7.如果把外部存储器接口(EMIF)设置在高端口则首先要把EMI0CF的PRTSEL位设置为1,选择高端口,同时选择地址的复用或非复用方式,在把XBR的外部寄存器的EMIFLE位设置为0。
8.复用方式配置:在复用方式下,数据总线和地址总线的第8位共用相同的引脚(AD0~AD7)。
在该方式下,要用一个外部锁存器(如 74HC373或相同功能的锁存器)保持RAM地址的低8位。
外部锁存器由ALE(地址锁存使能)信号控制,ALE信号由外部存储器接口逻辑驱动。
9.在总线复用时,需要把地址数据复用端口配置为漏极开路。
10.ALE高/低脉宽占1个SYSCLK周期,地址建立/保持时间占0个SYSCLK周期,/WR和/RD占12个SYSCLK周期,EMIF工作在地址/数据复用方式,即:EMI0CF |= 0x2c;EMI0TC |= 0x2c;配置EMIF 的步骤是:先将EMIF选到低端口或高端口;然后选择复用方式或非复用方式;再选择存储器的模式(只用片内存储器、不带块选择的分片方式、带块选择的分片方式或只用片外存储器);然后设置EMI0TC;最后通过寄存器PnMDOUT和P74OUT选择所期望的相关端口的输出方式。
简述51单片机adc转换流程英文版Brief Introduction to the ADC Conversion Process of the 51 MicrocontrollerThe 51 microcontroller is a popular choice for embedded systems due to its simplicity, reliability, and widespread availability. Among its many features, the microcontroller often includes an Analog-to-Digital Converter (ADC) that converts analog signals into digital formats, enabling precise control and data acquisition. In this article, we will briefly describe the ADC conversion process of the 51 microcontroller.1. Overview of ADC:An ADC converts analog signals, which continuously vary in amplitude, into digital signals represented by discrete values. The 51 microcontroller's ADC typically has a specific number of bits, determining the resolution of the conversion. For example,an 8-bit ADC can represent 256 discrete levels, while a 10-bit ADC can represent 1024 levels.2. The ADC Conversion Process:Initialization: Before performing an ADC conversion, the microcontroller needs to be initialized. This involves setting up the ADC module, configuring the input channels, selecting the desired resolution, and enabling the ADC.Start Conversion: Once initialized, the microcontroller can start the ADC conversion process. This usually involves setting a specific control bit to initiate the conversion.Sampling: During the sampling phase, the ADC captures the analog signal at the selected input channel. The duration of this phase depends on the ADC's sampling rate and the characteristics of the analog signal.Quantization: The captured analog signal is then quantized, which means it is rounded off to the nearest discrete level based on the ADC's resolution. For example, if the ADC is 8-bit,the analog signal will be rounded off to one of the 256 possible levels.Digital Output: After quantization, the ADC outputs the digital representation of the analog signal. This digital value can be read by the microcontroller for further processing or transmitted to other systems.3. Conclusion:The ADC conversion process in the 51 microcontroller involves initialization, starting the conversion, sampling the analog signal, quantizing it, and finally outputting the digital value. This process enables the microcontroller to process and respond to analog signals accurately, making it suitable for a wide range of applications in embedded systems.中文版简述51单片机ADC转换流程51单片机因其简洁性、可靠性和广泛的应用性,在嵌入式系统中备受欢迎。
#include"c8051f020.h"
#include"math.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define jpan P1 //定义键盘
float DA_data; //DA数据
unsigned char Dkey;
void SysclkInit(void) //晶振初始化{
unsigned int i;
OSCXCN=0x67;
for(i=0;i<256;i++);
while(!(OSCXCN&0x80));
OSCICN=0x88;
}
void DACInit(void) //DAC的初始化{
REF0CN=0x03;
DAC0CN=0x80;
DAC1CN=0x80;
}
void delay1(int ms) //延时
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void keyscan(void) //键盘扫描
{
uchar temp,key;
jpan=0x0F; //低四位输入delay1(1);
temp=jpan; //读P3口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1)
key=0;
else if(temp==2)
key=1;
else if(temp==4)
key=2;
else if(temp==8)
key=3;
else
key=16;
jpan=0xF0; //高四位输入
delay1(1);
temp=jpan; //读P3口
temp=temp&0xF0;
temp=~((temp>>4)|0xF0);
if(temp==1)
key=key+0;
else if(temp==2)
key=key+4;
else if(temp==4)
key=key+8;
else if(temp==8)
key=key+12;
else
key=16;
switch(key)
{
case 0 :key=2;break;
case 1 : key=1;break;
case 2 : key=12;break;
case 3 : key=3;break;
case 4 : key=13;break;
case 5 : key=0;break;
case 6 : key=15;break;
case 7 : key=14;break;
case 8 : key=8;break;
case 9 : key=7;break;
case 10 : key=10;break;
case 11 : key=9;break;
case 12 : key=5;break;
case 13 : key=4;break;
case 14 : key=11;break;
case 15 : key=6;break;
default: key=16;
}
if(key==7)
{
DA_data=DA_data+1000; }
if(key==8)
{
DA_data=DA_data+100; }
if(key==9)
{
DA_data=DA_data+10;
}
if(key==10)
{
DA_data=DA_data+1;
}
if(key==4)
{
DA_data=DA_data-1000;
}
if(key==5)
{
DA_data=DA_data-100;
}
if(key==6)
{
DA_data=DA_data-10;
}
if(key==11)
{
DA_data=DA_data-1;
}
jpan=0x0f;
while(jpan!=0x0f);
}
void keydown(void) //检测是否按下键盘
{
jpan=0xF0;
if(jpan!=0xF0)
{
delay1(60);
if(jpan!=0xf0)
{
keyscan();
Dkey=1;
}
delay1(60);
}
}
void main(void)
{
// float Date;
// float vc;
WDTCN=0xde;
WDTCN=0xad; //禁止看门狗定时
P1MDOUT=0xff; //P1口推挽
XBR2=0x40;//使能交叉开关
SysclkInit();//晶振初始化
DACInit(); //DAC初始化
while(1)
{
keydown(); //键盘检测
if(Dkey)
{
Dkey=0;
DAC0L=(unsigned int ) DA_data;//低字节数据寄存器DAC0H=((unsigned int)DA_data)>>8;//高字节
DAC1L=(unsigned int ) DA_data;
DAC1H=((unsigned int)DA_data)>>8;
}
}
}。