|
單片機(jī)采樣送can格式數(shù)據(jù),后端通過232轉(zhuǎn)can傳輸
單片機(jī)源程序如下:
- //////////////////////////////////////////////////////////////////////////////////////////////
- //編制的地面電源軟件。發(fā)生過數(shù)組超限的情況軟件仿真調(diào)試完成時(shí)間2010805, //
- // 該單片機(jī)的定時(shí)器、AD轉(zhuǎn)換器、串行口都與以前不同,需要特別注意。
- //////////////////////////////////////////////////////////////////////////////////////////////
- #include <STC15.H>
- // #include <absacc.h>
- // #include <math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- //buf[0]~buf[3]是報(bào)頭,buf[4]、buf[5]是輸出電壓BCD碼uf[6]、buf[7]是輸出電流BCD碼,buf[8]是輸出狀態(tài)標(biāo)志1,
- //buf[9]、buf[10]是溫度的BCD碼,buf[11]是輸入狀態(tài)標(biāo)志2,buf[12]、buf[13]暫時(shí)未使用。
- uchar idata buf[45]={1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2};
- uint idata bufint[40]={0x0001,0x0002,0x0004,0x0008,0x0016,0x0032,0x0064,0x0128,0x0256,0x0512,0x1024,0x2048,0x4096,0x8192};
- uchar code zifu1[40]={111,104,7,4,5,6,7,8,9,8,53,111,104,3,4,5,6,7,8,9,8,53,111,104,2,1,8,9,8,6,5,7,53};
- uchar code zifu2[20]={1,2,4,8,16,32,3,2,1,2,3,4,5,6,7};
- // unsigned int idata gz_time[10]={0,0,0,0,0};
- sbit ADC_1=P1^0; //電壓測量
- sbit ADC_2=P1^1; //電流測量
- sbit ADC_3=P1^2; //溫度測量
- sbit TS=P2^5; //調(diào)試開關(guān)
- sbit DJ=P2^1; //開關(guān)KGUAN
- sbit SJ=P2^0; //發(fā)收FS
- // sfr ADC_CONTR=0xBC; //ADC控制寄存器
- // sfr ADC_RES=0xBD; //ADRJ=0時(shí),ADC結(jié)果高8位;ADRJ=1時(shí),B1B0位ADC結(jié)果的高兩位ADC_RES9 ADC_ RES8
- // sfr ADC_RESL=0xBE; //ADRJ=0時(shí),B1B0位ADC結(jié)果的低兩位ADC_RES1 ADC_ RES0;ADRJ=1時(shí),ADC結(jié)果低8位
- // sfr WDT_CONTR=0xC1;
- // sfr AUXR=0x8E;
- // sfr AUXR1=0xA2;
- // sfr P1ASF=0x9D;
- // sfr CLK_DIV=0x97; //ADRJ控制ADC結(jié)果存放的位置
- // sfr T2H=0xD6; //需要定義,TH2不定義則不寫分頻系數(shù)進(jìn)0xD6,導(dǎo)致定時(shí)器2不工作,串行口不發(fā)送數(shù)據(jù),TI始終為0,不置1,無數(shù)據(jù)輸出。
- // sfr T2L=0xD7; //需要定義,TL2不定義則不寫分頻系數(shù)進(jìn)0xD7
- // sfr P3M1=0xb1;
- // sfr P3M0=0xb2;
- // sfr P2M1=0x95;
- // sfr P2M0=0x96;
- // sfr P1M1=0x91;
- // sfr P1M0=0x92;
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標(biāo)志位
- #define ADC_START 0x08 //ADC開始控制位
- void timer0_ISR ( ) interrupt 1 using 2 //10毫秒@11.0592MHz時(shí)鐘
- {
- buf[25]=buf[25]+1; //中斷次數(shù)計(jì)數(shù),也就是計(jì)時(shí)。buf[25]記錄中斷的次數(shù),達(dá)到10次后清零
- }
- void time0Init() //定時(shí)器0初始化
- {
- AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器0模式
- TL0=0x00; //10ms中斷一次,(10ms)TH0TL0=65536-11059200/12/100=55536=0xdc00,(10ms)TH0TL0=65536-12000000/12/100=55536=0xd8f0,
- TH0=0xdc; // TH0=0xdc;TL0=0x00.(50ms)H0TL0=65536-11059200/12/20=19456=0x4c00
- TF0=0; //清除TF0標(biāo)志
- TR0=1; //定時(shí)器0開始計(jì)時(shí)
- EA=1;
- ET0=1;
- }
- void inituart() //串行口、定時(shí)器0初始化函數(shù)
- {
- SCON=0x50; //串行口工作在方式1。01010000
- AUXR1=0x40; //將串口定義到P3.6、P3.7,AUXR1=01000000,
- AUXR |= 0x01; //定時(shí)器0、2不分頻,選擇定時(shí)器2作為串口1的波特率發(fā)生器
- T2H=0xff; //設(shè)定波特率重裝值TH2TL2=65536-11059200/4/11520/12=65516=0xffecTH2TL2=65536-12000000/4/9600/12=65510=0xffe6。
- T2L=0xe8; //9600bps@11.0592MHzTH2TL2=65536-11059200/4/9600/12=65512=0xffe8;TH2TL2=65536-11059200/4/1200/12=65344=0xff40
- PCON=0x00; //波特率不加倍
- AUXR |= 0x10; //TR2=1; //啟動T/C2
- P3M1=0x00;
- P3M0=0x00;
- }
- //void UartInit(void) //9600bps@11.0592MHz
- //{
- // SCON = 0x50; //8位數(shù)據(jù),可變波特率
- // AUXR |= 0x01; //串口1選擇定時(shí)器2為波特率發(fā)生器
- // AUXR &= 0xFB; //定時(shí)器2時(shí)鐘為Fosc/12,即12T
- // T2L = 0xE8; //設(shè)定定時(shí)初值
- // T2H = 0xFF; //設(shè)定定時(shí)初值
- // AUXR |= 0x10; //啟動定時(shí)器2
- //}
- void delay(uchar delay_time) //延時(shí)函數(shù)。
- {uchar n;
- uint m;
- for (n=0;n<delay_time;n++)
- {
- for (m=0;m<10;m++)
- WDT_CONTR=0x3C;
- }
- }
- void set_p1_adc_channel()
- {
- uchar n;
- P1=0x00;
- ADC_CONTR=0xE0; //開啟AD電源 (11100000)
- ADC_RES=0; //AD結(jié)果高位清0
- ADC_RESL=0; //AD結(jié)果低2位清0
- P1ASF=0x07; //P1^0、P1^1和P1^2設(shè)為AD口。
- n=1;
- delay(n); //穩(wěn)定電源延時(shí)。
- }
- void adcyang(uchar idata *d,q) /*A/D變換q將數(shù)據(jù)放在不同的位置*/
- {uchar i,j;
- ADC_CONTR=ADC_CONTR&0xE0; //a/d的數(shù)據(jù)存放:buf[35]buf[36]電壓、buf[37]buf[38]電流、buf[39]buf[40]溫度。
- i=0;
- ADC_CONTR=ADC_CONTR|i; //選擇P1^0進(jìn)行A/D轉(zhuǎn)換,采集電壓值
- i=8;
- ADC_CONTR=ADC_CONTR|i; //啟動A/D。
- j=0;
- while(j==0)
- {
-
- j=ADC_CONTR&0x10;
- if (buf[25]>0x05) // //調(diào)試用,防止不斷循環(huán)
- {j=0x01;}
- }
- i=0xEF;
- ADC_CONTR=ADC_CONTR&i; //清A/D標(biāo)志。
- d[q]=ADC_RES; //P1^0的A/D電壓值結(jié)果高8位。
- d[q+1]=ADC_RESL; //P1^0的A/D電壓值結(jié)果低2位。
- ADC_CONTR=ADC_CONTR&0xE0; //
- i=1;
- ADC_CONTR=ADC_CONTR|i; //選擇P1^1進(jìn)行A/D轉(zhuǎn)換,采集電流值,
- i=8;
- ADC_CONTR=ADC_CONTR|i; //啟動A/D。
- j=0;
- while(j==0)
- {
- j=ADC_CONTR&0x10;
- if (buf[25]>0x05) //調(diào)試用,防止不斷循環(huán)
- {j=0x01;}
- }
- i=0xEF;
- ADC_CONTR=ADC_CONTR&i; //清A/D標(biāo)志。
- d[q+2]=ADC_RES; //P1^1的A/D電流值結(jié)果高8位。
- d[q+3]=ADC_RESL; //P1^1的A/D電流值結(jié)果低2位。
- ADC_CONTR=ADC_CONTR&0xE0; //A/D準(zhǔn)備
- i=2;
- ADC_CONTR=ADC_CONTR|i; //選擇P1^2進(jìn)行A/D轉(zhuǎn)換。
- i=8;
- ADC_CONTR=ADC_CONTR|i; //啟動A/D。
- j=0;
- while(j==0)
- {
- j=ADC_CONTR&0x10;
- if (buf[25]>0x05) //調(diào)試用,防止不斷循環(huán)
- {j=0x01;}
- }
- i=0xEF;
- ADC_CONTR=ADC_CONTR&i; //清A/D標(biāo)志。
- d[q+4]=ADC_RES; //P1^2的A/D溫度值結(jié)果高8位。
- d[q+5]=ADC_RESL; //P1^2的A/D溫度值結(jié)果低2位。
- }
-
- void bcdzhuanhua(unsigned int m,uchar a)
- {
- uchar i,p,q,r;
- uint j,k,n,h,l,t;
- q=0;
- r=0;
- n=0;
-
- for(i=0;i<=14;i++) //二進(jìn)制位權(quán)存在,加上一個(gè)字分為4位的BCD碼。共檢查14位。15、16位沒有這么大的數(shù)。
- {
- //m是要轉(zhuǎn)換的值。
- j=m;
- j>>=i; //從最低位開始考察m。
- q=(uchar)j; //將j轉(zhuǎn)換換為字節(jié)
- q=0x01&q;
- if(q>0) //考察m的每一位。
- {
- k=bufint[i]; //bufint[i]是二進(jìn)制i的位權(quán)。
- h=0x000f;
- for(p=0;p<=3;p++) //p是BCD碼的位置
- {
- l=n;
- t=(k&h);
- if(t>0)
- {
- n=n+t; //k的每組四位值最大為9。n是十進(jìn)制數(shù)同樣。不用考慮k、與n的值超過9,但要考慮進(jìn)位。
- t=h;
- t<<=4;
- l=t&l;
- t=t&n;
- if(t>l) //考慮進(jìn)位
- {
- l=0x6666&h;
- n=n+l; //有進(jìn)位則加6
- }
- l=n&0x000f;
- if(l>=0x000a) //還需要檢查十分位是9的情況。
- {
- n=n-0x000a+0x0010; //減10向十位進(jìn)位。
- }
- l=n&0x00f0;
- if(l>=0x00a0)
- {
- n=n-0x00a0+0x0100; //減100向佰位進(jìn)位。
- }
- l=n&0x0f00;
- if(l>=0x0a00)
- {
- n=n-0x0a00+0x1000; //減1000向千位進(jìn)位。
- }
- }
- h<<=4;
- }
- }
- }
- j=0x00ff; //這里有錯(cuò),拆成一個(gè)字8位
- j=n&j;
- buf[a+2]=(uchar)j;
- j=0xff00;
- j=n&j;
- j>>=8;
- buf[a+1]=(uchar)j;
- }
- void test_v( uint m )
- {
- int f;
- uchar i;
- bufint[14]=m; //buf[14]是電壓的16進(jìn)制值。
- buf[8]=buf[8]&0xfc; //電壓正常,buf[8]是狀態(tài)字,狀態(tài)字的B0、B1置0.
- f=m-5200; //5200是520V電壓,f值小于5200V位是低壓狀態(tài)。
- if(f<0)
- {
- DJ=1; //發(fā)光二極管亮報(bào)警。
- SJ=1; //蜂鳴器報(bào)警
- buf[8]=buf[8]+0x02; //狀態(tài)字B1置1;
- }
- f=m-5800; //5800是580V電壓f值大于580V位是高壓狀態(tài)。
- if(f>0)
- {
- DJ=1; //發(fā)光二極管亮報(bào)警?
- SJ=1; //蜂鳴器報(bào)警
- buf[8]=buf[8]+0x01; //狀態(tài)字B0置1
- }
- i=buf[8]&0x1f;
- if(i==0)
- {
- DJ=0; //發(fā)光二極管停止報(bào)警
- SJ=0; //蜂鳴器停止報(bào)警
- }
- }
- void test_I( uint m )
- {
- int f;
- uchar i;
- bufint[15]= bufint[16]; // bufint[15]~ bufint[19]是每100ms采樣的電流值。
- bufint[16]= bufint[17];
- bufint[17]= bufint[18];
- bufint[18]= bufint[19];
- bufint[19]=m;
- buf[8]=buf[8]&0xe7; //電流正常,buf[8]是狀態(tài)字,狀態(tài)字的B3置0.
- f=bufint[15]-m;
- if(f>768) //768是電流掉9A的值,768=9/12*1024,處理掉電流報(bào)警。
- {
- DJ=1; //發(fā)光二極管亮報(bào)警。
- SJ=1; //蜂鳴器報(bào)警
- buf[8]=buf[8]+0x10; //狀態(tài)字B3置1;
- }
- f=m-853; //853是電流10A的值,853=10/12*1024
- if(f>=0) //超出10A電流報(bào)警。
- {
- DJ=1; //發(fā)光二極管亮報(bào)警。
- SJ=1; //蜂鳴器報(bào)警
- buf[8]=buf[8]+0x08; //狀態(tài)字B3置1;
- }
- i=buf[8]&0x1f;
- if(i==0)
- {
- DJ=0; //發(fā)光二極管停止報(bào)警
- SJ=0; //蜂鳴器停止報(bào)警
- }
-
- }
- void test_T( uint m )
- {
- int f;
- uchar i;
- bufint[20]=m; //bufint[20]是溫度的16進(jìn)制值。
- buf[8]=buf[8]&0xfb; //溫度正常,buf[8]是狀態(tài)字,狀態(tài)字的B2置0.
- f=m-700; //700是70度溫度f值大于70度是高溫狀態(tài)。
- if(f>0)
- {
- DJ=1; //發(fā)光二極管亮報(bào)警。
- SJ=1; //蜂鳴器報(bào)警。
- buf[8]=buf[8]+0x04; //狀態(tài)字B2置1。
- }
- i=buf[8]&0x1f;
- if(i==0)
- {
- DJ=0; //發(fā)光二極管停止報(bào)警
- SJ=0; //蜂鳴器停止報(bào)警
- }
- }
- void dsp_data_v( )
- {
- uchar i,a;
- uint k,m,j;
- a=0;
- j=0;
- k=0; //buf[35]、buf[36]是電壓的采樣值。
- i=buf[35]; //采樣電壓高位值送i
- k=(int)i;
- k<<=2; //高位置送字的高8位
- i=buf[36]; //采樣電壓低二位采樣值送i
- i=i&0x03;
- k=k+(int)i; //拼接為字
- m=k*5.8594; //電壓值乘以5.8594,600V電壓對應(yīng)5V直流取樣電壓1024個(gè)單位,顯示放大10倍,默認(rèn)最后一位為小數(shù)位。
- test_v(m);
- a=3; //buf[4]、buf[5]是電壓的BCD碼
- bcdzhuanhua(m,a);
- }
- void dsp_data_I( )
- {
- uchar i,a;
- uint k,m,j;
- a=0;
- j=0;
- k=0; //buf[37]、buf[38]是電流的采樣值?
- i=buf[37]; //采樣電流高位值送i
- k=(int)i;
- k<<=2; //高位置送字的高8位
- i=buf[38]; //采樣電流低二位采樣值送i
- i=i&0x03;
- k=k+(int)i; //拼接為字
- m=k*0.1171875; //電流值乘以0.1171875,12A電流對應(yīng)5V直流取樣電壓,對應(yīng)xxx.x的BCD4位碼,顯示放大10倍,默認(rèn)最后一位為小數(shù)位。
- test_I(k);
- a=5; //buf[6]、buf[7]是電流的BCD碼
- bcdzhuanhua(m,a);
- }
- void dsp_data_T( )
- {
- uchar i,a;
- uint k,m,j;
- a=0;
- j=0;
- k=0; //buf[39]、buf[40]是溫度的采樣值。
- i=buf[39]; //采樣電流高位值送i
- k=(int)i;
- k<<=2; //高位置送字的高8位
- i=buf[40]; //采樣電流低二位采樣值送i
- i=i&0x03;
- k=k+(int)i; //拼接為字
- m=k*0.976525; //溫度值乘以0.976525,100度溫度對應(yīng)5V直流取樣電壓,對應(yīng)xxx.x的BCD4位碼,如065.7度、105.6度。
- test_T(m);
- a=8; //buf[9]、buf[10]是溫度的BCD碼。
- bcdzhuanhua(m,a);
- }
-
- void send1(uchar idata *d,uchar n) //發(fā)送函數(shù)
- { uchar i;
- REN=0; //防止自發(fā)自收。
- for (i=0;i<=n;i++)
- {
- TI=0;
- SBUF=d[i]; //發(fā)一個(gè)現(xiàn)在的數(shù)據(jù)
- while (TI==0);
- TI=0; //等待發(fā)送出去
- if(i==11)
- {
- TS=!TS;
- } //發(fā)送一次數(shù)據(jù)取反一次。
- }
- REN=1;
- }
-
- void receive(uchar idata *d,uchar n) //接受函數(shù)接收14位身份加2位開關(guān)
- {
- uchar i;
- for(i=0;i<=n;i++)
- {while (RI==0)
- {
- if(buf[25]>=0x07)
- {
- i=12; //接收的數(shù)據(jù)不可用,SBUF的數(shù)據(jù)儲存到d[24]中丟棄。
- break;
- }
- }
- RI=0; //接收n個(gè)數(shù)據(jù);一般為12個(gè)。
- d[i+12]=SBUF; //接收一個(gè)數(shù)據(jù),放在 d[i+m]處
- }
- }
-
-
- void main()
-
- {
- //buf[0]~buf[3]是報(bào)頭,buf[4]、buf[5]是輸出電壓BCD碼uf[6]、buf[7]是輸出電流BCD碼,buf[8]是輸出狀態(tài)標(biāo)志1,
- //buf[9]、buf[10]是溫度BCD碼,buf[11]是輸入狀態(tài)標(biāo)志2,
- buf[0]=0x1c; buf[1]=0xff; buf[2]=0x50; buf[3]=0xe7; buf[4]=0x00;
- buf[5]=zifu1[5]; buf[6]=zifu1[6]; buf[7]=zifu1[7]; buf[8]=0x00; buf[9]=zifu1[9];
- buf[10]=zifu1[10]; buf[11]=0x00; buf[12]=0x00; buf[13]=zifu1[13]; buf[14]=zifu1[14];
- buf[15]=zifu1[15]; buf[16]=zifu1[16]; buf[17]=zifu1[17]; buf[18]=zifu1[18]; buf[19]=zifu1[19];
- buf[20]=zifu1[20]; buf[21]=zifu1[21]; buf[22]=zifu1[22]; buf[23]=zifu1[23];
- bufint[23]=1222;
- // buf[39]=zifu1[24];
- //buf[25]=zifu1[25]; buf[26]=zifu1[26]; buf[27]=zifu1[27]; buf[28]=zifu1[28]; buf[29]=zifu1[29];
- //buf[30]=zifu1[30]; buf[31]=zifu1[31]; buf[32]=zifu1[32];
- time0Init(); //定時(shí)器0初始化
- inituart(); //串行口初始化 定時(shí)器2初始化//
- P1=0x00;
- P2=0x00;
- P3=0x80;
- for(; ;) //主程序循環(huán)執(zhí)行。
- {
- uchar n,k;
- set_p1_adc_channel(); //AD采樣初始化
- if (buf[25]>0x09) //100ms時(shí)間值0x0a。
- {
- buf[34]= buf[34]+1; //記錄100ms時(shí)間的次數(shù)
- buf[25]=0; //buf[25]記錄10ms一次的時(shí)間,100ms時(shí)間到清零。其值為:
- n=35; //a/d的數(shù)據(jù)存放:buf[35]buf[36]電壓、buf[37]buf[38]電流、buf[39]buf[40]溫度。
- adcyang(buf,n); //A/D采樣。
- dsp_data_v( ); //對電壓值進(jìn)行處理
- dsp_data_I( ); //對電流值進(jìn)行處理
- dsp_data_T( ); //對溫度值進(jìn)行處理
- }
- if (buf[34]>0x04) //500ms時(shí)間到,發(fā)送一次數(shù)據(jù)。
- {
- buf[34]=0; //發(fā)送完數(shù)據(jù)清零buf[34],500ms清零。
- k=11; //一共發(fā)送12個(gè)數(shù)據(jù),從d[0]~d[11]。
- send1(buf,k);
- }
- n=11; //接收數(shù)據(jù)一幀為12個(gè)數(shù)據(jù)
- receive(buf,n);
- WDT_CONTR=0x34;
- n=1;
- delay(n);
- }
- }
- //2017年編制的電壓電流溫度測量軟件,處理并發(fā)送數(shù)據(jù)。
復(fù)制代碼
所有資料51hei提供下載:
備份.zip
(8.27 KB, 下載次數(shù): 9)
2019-4-24 09:08 上傳
點(diǎn)擊文件名下載附件
單片機(jī)程序 下載積分: 黑幣 -5
|
|