首页 C8051F学习日记

C8051F学习日记

举报
开通vip

C8051F学习日记一、C8051F学习日记 今天开始每天把学习C8051F的感受记下来    今天上传一个AD采集交流电的程序50HZ的交流电经过精密整流以后每个周期单通道采集800个点分两个通道采集电压和电流并计算S,P,Q,相位角g ;   感觉玩C8051F的AD好爽啊   还有DA    功能强啊   就是爽            /*******************************************************************                 C8051F020 AD采...

C8051F学习日记
一、C8051F学习日记 今天开始每天把学习C8051F的感受记下来    今天上传一个AD采集交流电的程序50HZ的交流电经过精密整流以后每个周期单通道采集800个点分两个通道采集电压和电流并计算S,P,Q,相位角g ;   感觉玩C8051F的AD好爽啊   还有DA    功能强啊   就是爽            /*******************************************************************                 C8051F020 AD采集         2006.09.26 *******************************************************************/ /************************预定义************************************/ #i nclude #i nclude #i nclude #i nclude /*******************************************************************                            定义IO口和变量 *******************************************************************/ sbit LCDBUSY = P3^0; //LCD忙信号位 sbit REQ = P3^1;     //LCD请求信号位 sbit RES = P3^2;     //LCD复位信号位 sfr16 ADC0 = 0xbe; unsigned int xdata ADC0_data1[800]; //AD通道一采集数据存放数组 unsigned int xdata ADC0_data2[800]; //AD通道二采集数据存放数组 unsigned int data ADC0_data_n;      //AD采集次数 unsigned int data ADC0_data_n1;     //通道一采集次数 unsigned int data ADC0_data_n2;     //通道二采集次数 bit m;//AD采集完标志 /*******************************************************************                             函数声明 *******************************************************************/ void Sjcl(void);//AD采集完100次数据处理函数 void ADC0_ISR(void);//ADC0中断函数声明 void write_data(unsigned char writedata);//写数据到LCD void send_ascii8(unsigned char x,unsigned char y,unsigned char ascii);//显示8*8ASCII /********************************************************************                         子函数定义 ********************************************************************/ void delay_us(int timer)//us沿时 {    timer*=20;//时钟周期调整   for(;timer>0;timer--)   _nop_(); } void delay_ms(int i)//ms沿时 {   for(;i>0;i--)   delay_us(1000); } void lcd_init(void)//lcd初始化 {   RES=0;   delay_ms(20);   RES=1;   REQ=0;   LCDBUSY=0; } /********************************************************************                         系统初始化函数 ********************************************************************/ void UART_Init() {     SCON0     = 0x50;   //使能UART0并允许接收 } void Timer_Init()                    {     CKCON     = 0x10;     TCON      = 0x40;     TMOD      = 0x20;     TH1       = 0xB8;  //用定时器3做为AD0的启动转换标志每100us启动一次采集,                  TMR3CN    = 0x04;  //使用系统时钟12分频做为定时器3的时钟源(22.1184M)     TMR3RLL   = 0xd1;  //T1使用系统时钟并产生9600的波特率用与UART0     TMR3RLH   = 0xFF;     TMR3L     = 0xd1;     TMR3H     = 0xFF; } void ADC_Init() {     ADC0CF    = 0x40;   //ADC0为定时器3益处采集方式,时钟频率为2.5M,     ADC0CN    = 0x04;   //增益为1,数据为右对齐方式                     AMX0SL=0X00;       } void Voltage_Reference_Init() {     REF0CN    = 0x03;    //ADC0的参考电压来自内部增益 } void Port_IO_Init()  //IO口初始化                    {     P0MDOUT   = 0x01;     //P0.0,P0.1做为UART0的通信引脚,其中TX0为推拉方式     P3MDOUT   = 0x06;     //P3.0为BUSY读取引脚,设为开漏方式                        //P3.1为请求标志位设为推拉方式                  //P3.2为复位信号脚设置为推拉方式     P74OUT    = 0x03;     //P4为液晶数据线设为推拉方式     XBR0      = 0x04;     XBR2      = 0x40; } void Oscillator_Init()//使用外部晶振22.1184M {     int i = 0;     OSCXCN    = 0x67;     for (i = 0; i < 3000; i++);   // Wait 1ms for initialization     while ((OSCXCN & 0x80) == 0);     OSCICN    = 0x08; } void Interrupts_Init() {   EIE2 = 0x02;   //允许ADC0中断   } void Init_Device(void) {     Timer_Init();     UART_Init();     ADC_Init();     Voltage_Reference_Init();   //初始化主程序     Port_IO_Init();     Oscillator_Init();     Interrupts_Init(); } //end init// /****************************************************************************                               主函数定义开始 *****************************************************************************/ void main(void) {     WDTCN=0xde;     WDTCN=0xad;        //关看门狗     Init_Device();     lcd_init();     AD0EN=1;     delay_ms(5);     EA=1;     TI0=1;     while(1)     {       if(m==1)       {               m=0;          TMR3CN&=0xFB;  //关定时器3          Sjcl();        //处理数据          TMR3CN|=0X04;   //开定时器3       }     } } /****************************************************************************                                                 ADC0中断处理 ****************************************************************************/ void ADC0_ISR(void) interrupt 15  {     ADC0CN&=0xdf;     if(ADC0_data_n%2==0)  {         ADC0_data1[ADC0_data_n1] = ADC0;   ADC0_data_n1++;         AMX0SL = 0x01;      }     else  {      ADC0_data2[ADC0_data_n2]=ADC0;   ADC0_data_n2++;   AMX0SL=0x00;      }     ADC0_data_n++;     if(ADC0_data_n==1600)//两路采集完800点     {        m=1;     } } /****************************************************************************                                                 数据采集完处理函数 ****************************************************************************/ void Sjcl(void) {     /*unsigned int j;*/    /*unsigned char xdata lcd_senddata[4];//四位LCD显示数据*/    unsigned int i;    unsigned long data ADC0_dataadd=0;//采集完毕的累加计算值    unsigned long data a=0;    unsigned long data b=0;    float data c;    float data d;    float data P_dataadd=0;    float data U=0;    float data I=0;               float data S=0;    float data P=0;    float data Q=0;    float data COSg=0;    //通道一数据处理          for(i=0;i<=ADC0_data_n1;i++)    {       a=ADC0_data1[i];       ADC0_dataadd=ADC0_dataadd+a*a;    }    U=ADC0_dataadd/ADC0_data_n1;//取平均值    U=sqrt(U);//取平方根值    U=(U*2.451)/0x0fff;//计算实际电压值       //通道二数据处理     ADC0_dataadd=0;     for(i=0;i<=ADC0_data_n2;i++)    {       a=ADC0_data2[i];       ADC0_dataadd=ADC0_dataadd+a*a;    }    I=ADC0_dataadd/ADC0_data_n2;//取平均值    I=sqrt(I);//取平方根值    I=(I*2.451)/0x0fff;//计算实际电压2值    S=U*I;    for(i=0;i<=ADC0_data_n1;i++) //计算P值    {      c=((float)ADC0_data1[i]*2.451)/0x0fff;      d=((float)ADC0_data1[i]*2.451)/0x0fff;      P_dataadd=P_dataadd+c*d;     }    P=P_dataadd/ADC0_data_n1;//取平均值    Q=sqrt(S*S-P*P);//计算Q值    COSg=P/S;//计算cosg值    printf("************************************\n");    delay_ms(10);    printf("U=%.3fv   I=%.3fv\n",U,I);    delay_ms(10);    printf("S=%.3fw   P=%.3fw   Q=%.3fw\n",S,P,Q);    delay_ms(10);    printf("COSg=%.3f\n",COSg);    delay_ms(10);    ADC0_data_n=0;    ADC0_data_n1=0;    ADC0_data_n2=0; } 二、C8051F020中ADC的使用方法 [ 2006-9-23 22:12:48 | By: huolf ] void init_vref(void) {     REF0CN=0x03;    //0x03            //允许参考电压发生器(b1)及其缓冲器x2(b0),参考电压从VREF引脚输出                                 //ADC0参考电压取自VREF0引脚(b4),ADC1参考电压取 自VREF1引脚(b3);禁止并使用外部参考是0x02 } void init_adc0(void)            //系统时钟=12M {     ADC0CF=0x28;                //ADC0配置寄存 器,设置转换时钟(SAR<=2.5M)和内部放大器增益,SAR转换时钟                                 //=系统时钟/(b7-b3)=2M,内部放大器增益=1(b2-b0)     AMX0SL=0x00;                //模拟输入通道选 择寄存器(b3-0),             ADC0CN=0x80;                //ADC0控制寄存 器,允许ADC(b7),向AD0BUSY写1启动ADC(b3-b2)     AMX0CF=0x00;                //模拟输入方式配 置寄存器,(b3-0=0:AIN0-7是独立的单端输入,否则成队配置                                 //为差分输入),对于被配置成差分输入的通道,ADC数 据字格式为2的补码     EIE2=EIE2|0x02;                //允许ADC0中 断,EADC0=1,EIE2.1=1 } void adc0(void) interrupt 15 using 3        //ADC0中断服务程序 {     if(AD0INT)     {         AD0INT=0;         adc0_result=ADC0H;         adc0_result=adc0_result<<8;         adc0_result=(adc0_result|ADC0L)&0x0fff;    //020是12位ADC         adc0_over=1;     } } uint start_adc0(uchar channel,uchar adc_time)//adc_time是参与取平均的次数 {     uchar xdata i,j;     ulong xdata n=0;     for(j=0;j<40;j++)     {         wdog=1;         for(i=0;i=0;i--)     for(j=255;j>=0;j--);  } /*************************************************************/   void SYSCLK_Init (void) {  int i;  OSCXCN=0x67;  for(i=255;i>=0;i--);  while (!(OSCXCN & 0x80)) ;    //11.059m hz  OSCICN=0x88; } void UART0_Init (void) {    SCON0   = 0x50;                     // SCON0: mode 1, 8-bit UART, enable RX    TMOD    = 0x20;                     // TMOD: timer 1, mode 2, 8-bit reload    TH1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate      TL1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate    TR1    = 1;                         // start Timer1    CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base    PCON  |= 0x80;                      // SMOD00 = 1    TI0    = 1;                         // Indicate TX0 ready } void init_port() //初始化端口 {    P1 = 0xFF;     P2 = 0xFF;  P3 = 0xFF;  P3MDOUT=0xff;    //pull-push MODE  P2MDOUT=0x00;  //open-drain MODE  P1MDOUT=0xff;    //pull-push MODE }     void main(void)  //initial micro controller {   unsigned char i;   WDTDISABLE;   SYSCLK_Init();     XBR0 = 0x04; // XBAR0: Initial Reset Value   XBR1 = 0x04; // XBAR1: Initial Reset Value   XBR2 = 0x40; // XBAR2: Initial Reset Value      init_port();   UART0_Init ();   P2MDOUT=0x00;   P2=0xff; //接受数字输入     while(1)   {     for(i=0xff;i>0;i--)  {     P2MDOUT=0x00;        P2=0xff;    P1=i;    printf("Now P2=%x\n",P2);    DELAY();  }   } }
本文档为【C8051F学习日记】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_988301
暂无简介~
格式:doc
大小:51KB
软件:Word
页数:12
分类:互联网
上传时间:2014-03-14
浏览量:15