久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機采樣送can格式數據的源程序
[打印本頁]
作者:
wl19900429
時間:
2019-4-24 09:09
標題:
單片機采樣送can格式數據的源程序
單片機采樣送can格式數據,后端通過232轉can傳輸
單片機源程序如下:
//////////////////////////////////////////////////////////////////////////////////////////////
//編制的地面電源軟件。發生過數組超限的情況軟件仿真調試完成時間2010805, //
// 該單片機的定時器、AD轉換器、串行口都與以前不同,需要特別注意。
//////////////////////////////////////////////////////////////////////////////////////////////
#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]是報頭,buf[4]、buf[5]是輸出電壓BCD碼uf[6]、buf[7]是輸出電流BCD碼,buf[8]是輸出狀態標志1,
//buf[9]、buf[10]是溫度的BCD碼,buf[11]是輸入狀態標志2,buf[12]、buf[13]暫時未使用。
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; //調試開關
sbit DJ=P2^1; //開關KGUAN
sbit SJ=P2^0; //發收FS
// sfr ADC_CONTR=0xBC; //ADC控制寄存器
// sfr ADC_RES=0xBD; //ADRJ=0時,ADC結果高8位;ADRJ=1時,B1B0位ADC結果的高兩位ADC_RES9 ADC_ RES8
// sfr ADC_RESL=0xBE; //ADRJ=0時,B1B0位ADC結果的低兩位ADC_RES1 ADC_ RES0;ADRJ=1時,ADC結果低8位
// sfr WDT_CONTR=0xC1;
// sfr AUXR=0x8E;
// sfr AUXR1=0xA2;
// sfr P1ASF=0x9D;
// sfr CLK_DIV=0x97; //ADRJ控制ADC結果存放的位置
// sfr T2H=0xD6; //需要定義,TH2不定義則不寫分頻系數進0xD6,導致定時器2不工作,串行口不發送數據,TI始終為0,不置1,無數據輸出。
// sfr T2L=0xD7; //需要定義,TL2不定義則不寫分頻系數進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完成標志位
#define ADC_START 0x08 //ADC開始控制位
void timer0_ISR ( ) interrupt 1 using 2 //10毫秒@11.0592MHz時鐘
{
buf[25]=buf[25]+1; //中斷次數計數,也就是計時。buf[25]記錄中斷的次數,達到10次后清零
}
void time0Init() //定時器0初始化
{
AUXR &= 0x7F; //定時器時鐘12T模式
TMOD &= 0xF0; //設置定時器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標志
TR0=1; //定時器0開始計時
EA=1;
ET0=1;
}
void inituart() //串行口、定時器0初始化函數
{
SCON=0x50; //串行口工作在方式1。01010000
AUXR1=0x40; //將串口定義到P3.6、P3.7,AUXR1=01000000,
AUXR |= 0x01; //定時器0、2不分頻,選擇定時器2作為串口1的波特率發生器
T2H=0xff; //設定波特率重裝值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位數據,可變波特率
// AUXR |= 0x01; //串口1選擇定時器2為波特率發生器
// AUXR &= 0xFB; //定時器2時鐘為Fosc/12,即12T
// T2L = 0xE8; //設定定時初值
// T2H = 0xFF; //設定定時初值
// AUXR |= 0x10; //啟動定時器2
//}
void delay(uchar delay_time) //延時函數。
{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結果高位清0
ADC_RESL=0; //AD結果低2位清0
P1ASF=0x07; //P1^0、P1^1和P1^2設為AD口。
n=1;
delay(n); //穩定電源延時。
}
void adcyang(uchar idata *d,q) /*A/D變換q將數據放在不同的位置*/
{uchar i,j;
ADC_CONTR=ADC_CONTR&0xE0; //a/d的數據存放:buf[35]buf[36]電壓、buf[37]buf[38]電流、buf[39]buf[40]溫度。
i=0;
ADC_CONTR=ADC_CONTR|i; //選擇P1^0進行A/D轉換,采集電壓值
i=8;
ADC_CONTR=ADC_CONTR|i; //啟動A/D。
j=0;
while(j==0)
{
j=ADC_CONTR&0x10;
if (buf[25]>0x05) // //調試用,防止不斷循環
{j=0x01;}
}
i=0xEF;
ADC_CONTR=ADC_CONTR&i; //清A/D標志。
d[q]=ADC_RES; //P1^0的A/D電壓值結果高8位。
d[q+1]=ADC_RESL; //P1^0的A/D電壓值結果低2位。
ADC_CONTR=ADC_CONTR&0xE0; //
i=1;
ADC_CONTR=ADC_CONTR|i; //選擇P1^1進行A/D轉換,采集電流值,
i=8;
ADC_CONTR=ADC_CONTR|i; //啟動A/D。
j=0;
while(j==0)
{
j=ADC_CONTR&0x10;
if (buf[25]>0x05) //調試用,防止不斷循環
{j=0x01;}
}
i=0xEF;
ADC_CONTR=ADC_CONTR&i; //清A/D標志。
d[q+2]=ADC_RES; //P1^1的A/D電流值結果高8位。
d[q+3]=ADC_RESL; //P1^1的A/D電流值結果低2位。
ADC_CONTR=ADC_CONTR&0xE0; //A/D準備
i=2;
ADC_CONTR=ADC_CONTR|i; //選擇P1^2進行A/D轉換。
i=8;
ADC_CONTR=ADC_CONTR|i; //啟動A/D。
j=0;
while(j==0)
{
j=ADC_CONTR&0x10;
if (buf[25]>0x05) //調試用,防止不斷循環
{j=0x01;}
}
i=0xEF;
ADC_CONTR=ADC_CONTR&i; //清A/D標志。
d[q+4]=ADC_RES; //P1^2的A/D溫度值結果高8位。
d[q+5]=ADC_RESL; //P1^2的A/D溫度值結果低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++) //二進制位權存在,加上一個字分為4位的BCD碼。共檢查14位。15、16位沒有這么大的數。
{
//m是要轉換的值。
j=m;
j>>=i; //從最低位開始考察m。
q=(uchar)j; //將j轉換換為字節
q=0x01&q;
if(q>0) //考察m的每一位。
{
k=bufint[i]; //bufint[i]是二進制i的位權。
h=0x000f;
for(p=0;p<=3;p++) //p是BCD碼的位置
{
l=n;
t=(k&h);
if(t>0)
{
n=n+t; //k的每組四位值最大為9。n是十進制數同樣。不用考慮k、與n的值超過9,但要考慮進位。
t=h;
t<<=4;
l=t&l;
t=t&n;
if(t>l) //考慮進位
{
l=0x6666&h;
n=n+l; //有進位則加6
}
l=n&0x000f;
if(l>=0x000a) //還需要檢查十分位是9的情況。
{
n=n-0x000a+0x0010; //減10向十位進位。
}
l=n&0x00f0;
if(l>=0x00a0)
{
n=n-0x00a0+0x0100; //減100向佰位進位。
}
l=n&0x0f00;
if(l>=0x0a00)
{
n=n-0x0a00+0x1000; //減1000向千位進位。
}
}
h<<=4;
}
}
}
j=0x00ff; //這里有錯,拆成一個字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進制值。
buf[8]=buf[8]&0xfc; //電壓正常,buf[8]是狀態字,狀態字的B0、B1置0.
f=m-5200; //5200是520V電壓,f值小于5200V位是低壓狀態。
if(f<0)
{
DJ=1; //發光二極管亮報警。
SJ=1; //蜂鳴器報警
buf[8]=buf[8]+0x02; //狀態字B1置1;
}
f=m-5800; //5800是580V電壓f值大于580V位是高壓狀態。
if(f>0)
{
DJ=1; //發光二極管亮報警?
SJ=1; //蜂鳴器報警
buf[8]=buf[8]+0x01; //狀態字B0置1
}
i=buf[8]&0x1f;
if(i==0)
{
DJ=0; //發光二極管停止報警
SJ=0; //蜂鳴器停止報警
}
}
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]是狀態字,狀態字的B3置0.
f=bufint[15]-m;
if(f>768) //768是電流掉9A的值,768=9/12*1024,處理掉電流報警。
{
DJ=1; //發光二極管亮報警。
SJ=1; //蜂鳴器報警
buf[8]=buf[8]+0x10; //狀態字B3置1;
}
f=m-853; //853是電流10A的值,853=10/12*1024
if(f>=0) //超出10A電流報警。
{
DJ=1; //發光二極管亮報警。
SJ=1; //蜂鳴器報警
buf[8]=buf[8]+0x08; //狀態字B3置1;
}
i=buf[8]&0x1f;
if(i==0)
{
DJ=0; //發光二極管停止報警
SJ=0; //蜂鳴器停止報警
}
}
void test_T( uint m )
{
int f;
uchar i;
bufint[20]=m; //bufint[20]是溫度的16進制值。
buf[8]=buf[8]&0xfb; //溫度正常,buf[8]是狀態字,狀態字的B2置0.
f=m-700; //700是70度溫度f值大于70度是高溫狀態。
if(f>0)
{
DJ=1; //發光二極管亮報警。
SJ=1; //蜂鳴器報警。
buf[8]=buf[8]+0x04; //狀態字B2置1。
}
i=buf[8]&0x1f;
if(i==0)
{
DJ=0; //發光二極管停止報警
SJ=0; //蜂鳴器停止報警
}
}
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電壓對應5V直流取樣電壓1024個單位,顯示放大10倍,默認最后一位為小數位。
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電流對應5V直流取樣電壓,對應xxx.x的BCD4位碼,顯示放大10倍,默認最后一位為小數位。
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度溫度對應5V直流取樣電壓,對應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) //發送函數
{ uchar i;
REN=0; //防止自發自收。
for (i=0;i<=n;i++)
{
TI=0;
SBUF=d[i]; //發一個現在的數據
while (TI==0);
TI=0; //等待發送出去
if(i==11)
{
TS=!TS;
} //發送一次數據取反一次。
}
REN=1;
}
void receive(uchar idata *d,uchar n) //接受函數接收14位身份加2位開關
{
uchar i;
for(i=0;i<=n;i++)
{while (RI==0)
{
if(buf[25]>=0x07)
{
i=12; //接收的數據不可用,SBUF的數據儲存到d[24]中丟棄。
break;
}
}
RI=0; //接收n個數據;一般為12個。
d[i+12]=SBUF; //接收一個數據,放在 d[i+m]處
}
}
void main()
{
//buf[0]~buf[3]是報頭,buf[4]、buf[5]是輸出電壓BCD碼uf[6]、buf[7]是輸出電流BCD碼,buf[8]是輸出狀態標志1,
//buf[9]、buf[10]是溫度BCD碼,buf[11]是輸入狀態標志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(); //定時器0初始化
inituart(); //串行口初始化 定時器2初始化//
P1=0x00;
P2=0x00;
P3=0x80;
for(; ;) //主程序循環執行。
{
uchar n,k;
set_p1_adc_channel(); //AD采樣初始化
if (buf[25]>0x09) //100ms時間值0x0a。
{
buf[34]= buf[34]+1; //記錄100ms時間的次數
buf[25]=0; //buf[25]記錄10ms一次的時間,100ms時間到清零。其值為:
n=35; //a/d的數據存放:buf[35]buf[36]電壓、buf[37]buf[38]電流、buf[39]buf[40]溫度。
adcyang(buf,n); //A/D采樣。
dsp_data_v( ); //對電壓值進行處理
dsp_data_I( ); //對電流值進行處理
dsp_data_T( ); //對溫度值進行處理
}
if (buf[34]>0x04) //500ms時間到,發送一次數據。
{
buf[34]=0; //發送完數據清零buf[34],500ms清零。
k=11; //一共發送12個數據,從d[0]~d[11]。
send1(buf,k);
}
n=11; //接收數據一幀為12個數據
receive(buf,n);
WDT_CONTR=0x34;
n=1;
delay(n);
}
}
//2017年編制的電壓電流溫度測量軟件,處理并發送數據。
復制代碼
所有資料51hei提供下載:
備份.zip
(8.27 KB, 下載次數: 9)
2019-4-24 09:08 上傳
點擊文件名下載附件
單片機程序
下載積分: 黑幣 -5
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
久久精品亚洲
|
www.伊人.com
|
中文视频在线
|
日本在线看
|
精品国产一区二区在线
|
亚洲一区二区视频在线播放
|
成人免费大片黄在线播放
|
欧美在线免费
|
国产精品日本一区二区在线播放
|
天天干夜夜操
|
亚洲精品一区二区在线观看
|
中文二区
|
午夜a√
|
在线免费观看视频黄
|
国产探花在线观看视频
|
男女网站在线观看
|
天堂素人约啪
|
久久蜜桃资源一区二区老牛
|
国产精品久久久久久久久久久久冷
|
国产综合久久久久久鬼色
|
欧美狠狠操
|
国产精品麻
|
人人种亚洲
|
国产黄色在线观看
|
国产高清在线视频
|
久久精品一区二区
|
99免费在线视频
|
国产福利91精品一区二区三区
|
国产情侣久久
|
亚洲精品视频免费
|
亚洲一区二区中文字幕
|
久草新在线
|
免费国产视频
|
欧美一区二区视频
|
亚洲视频一区在线观看
|
欧美性受xxxx白人性爽
|
性生生活大片免费看视频
|
日韩视频在线免费观看
|
中文字幕一页二页
|
涩涩视频在线观看
|
日韩激情一区
|