基于PIC16F73的下位機(jī)串口通訊設(shè)計(jì)備忘
基本功能要求:
本文引用地址:http://2s4d.com/article/201608/296034.htm接收上位機(jī)所給的設(shè)定命令,并根據(jù)命令進(jìn)行相應(yīng)的操作,同時(shí)下位機(jī)將采集到的信息上傳給上位機(jī)處理顯示等。
具體細(xì)節(jié)設(shè)計(jì):
由于本設(shè)計(jì)主要針對(duì)本公司的高壓電源的,關(guān)于采集到的輸出高壓反饋值的模擬量可以利用單片機(jī)內(nèi)部集成的8位AD轉(zhuǎn)換模塊,
而電源的設(shè)定電壓采用單片機(jī)內(nèi)部的PWM模塊來(lái)實(shí)現(xiàn)8位的DA轉(zhuǎn)換,
具體程序如下:(初稿)
//***********************************************************
//-------------- 源文件名為:RS232.c-----
//監(jiān)控高壓源71520的工作,開(kāi)啟高壓,上位機(jī)可以設(shè)定高壓值
//同時(shí)可以監(jiān)控反饋高壓值,采用最簡(jiǎn)通訊模式
//
//******************************************
#include
#include
__CONFIG(XT & WDTDIS& PWRTDIS & BORDIS & PROTECT );//配置字
void DELAY(int time);
void initPORTB();
void initPORTA();
void initPORTC();
void inittmr2();
void initCCP1();
//變量定義
unsigned char recdata,RX[8],i,j,k,AD_result; //0-255
unsigned char TX[8]={0x42,0x72,0x55,0x32,0x35,0x35,0x46,0x50};//BrU255FP
//int AD_result;
//------------------初始化 PORTB--------
void initPORTB()
{ TRISB=0xe0; //設(shè)置portb口高3位為輸入,低5位為輸出
RBIE=1; //關(guān)閉B口的中斷
PORTB=0x00; //RB口先送高電平清除干擾
}
//-----------------初始化 PORTA----------
void initPORTA() //包含AD轉(zhuǎn)換初始化
{ TRISA=0x3f; //設(shè)置portA口 輸入
ADCON1=0x00; //A口全為AD口,RA0,1,2,3,5為模擬口,考電壓VDD
ADCON0=0x85; //fosc/32,通道0-85,8D-chanl1,開(kāi)啟轉(zhuǎn)換
ADIE=1; //允許中斷
}
//------------------初始化 PORTC--------
void initPORTC() //包含波特率設(shè)置
{ TRISC=0xC0; //設(shè)置portC口狀態(tài),RC7/RX為輸入
TXSTA=0XA6;
RCSTA=0XB0; //使能串口,8位連續(xù)接收,B0連續(xù)接受
PIR1=0X00; //清標(biāo)志位
RCIE=1; //接受中斷
TXIE=1; //發(fā)送中斷
PORTC=0x00; //RC口賦初值
SPBRG=25; //9600-25(10進(jìn)制)
}
//---------------初始化 tmr2------------------
void inittmr2()
{ TMR2 =0; //賦初值,
T2CON=0x72; //0x72后分頻為1:8,預(yù)分頻為1:16,先關(guān)閉.,31-4后分頻,4預(yù)分頻
// TMR2IE=1; //開(kāi)/關(guān)定時(shí)器2中斷,清標(biāo)志位
TMR2IF=0;
TMR2ON=1; //啟動(dòng)定時(shí)器2
}
//---------------初始化 CCP1 ------------------
void initCCP1()
{
CCP1IF=0; //清標(biāo)志位
CCP1CON=0X0c; //設(shè)置工作模式
//Pwm模式
CCP1IE=1; //關(guān)閉中斷
PR2=0XFF; //定時(shí)器2的最大周期 245hZ
CCPR1L=0X0f; //預(yù)制一個(gè)數(shù)
CCPR1H=0; //,通過(guò)改變CCPR1L的值即可實(shí)現(xiàn)占空比的改變
}
void interrupt all_int()
{
//首先判斷中斷的類(lèi)型,執(zhí)行不同的中斷子程序
//中斷優(yōu)先級(jí)依次為接收中斷、AD轉(zhuǎn)換中斷、發(fā)送中斷
if(RCIF&&RCIE) //判斷是否是串口接收中斷
{
// RB1=1;
RCIF=0;//清干擾
recdata=RCREG; // 接收數(shù)據(jù)并存儲(chǔ)
RX[i]=recdata;
i=i+1;
}
//------AD轉(zhuǎn)換中斷----
if(ADIF&&ADIE)
{
ADIF=0;//清干擾
RB2=1;
k=55;
AD_result=ADRES;
ADCON0=0x85;
;
}
//-------發(fā)送中斷-----
if(TXIF&&TXIE)
{
RB3=1;
TXIF=0;//清干擾
TXREG=TX[j];
j=j+1;
if(j>=8)
{j=0;}
}
}
//軟件延時(shí)子程序
void DELAY(int time)
{
int x,y;
for(x=0;x<50;x++)
{
for(y=0;y }
}
//--------------------主程序------------------------
main()
{
initPORTB(); //PORTB初始化
initPORTA(); //PORTA初始化
initPORTC(); //PORTC初始化
inittmr2();
initCCP1();
GIE=1; //開(kāi)啟全局中斷
PEIE=1; //開(kāi)啟外圍中斷
RB2=0;
RB1=0;
RB3=0;
k=56;
while(1)
{
//---------取出AD轉(zhuǎn)換的百位、十位、個(gè)位-----
if(k==55)
{
RB4=1;
ADIE=0;//數(shù)據(jù)傳輸期間禁止更改
TX[3]=(AD_result/100)+48;
TX[4]=((AD_result%100-AD_result%10)/10)+48;
TX[5]=(AD_result%10)+48;
k=56;
ADIE=1;
ADCON0=0x85;//開(kāi)啟轉(zhuǎn)換
}
if(i>=8)//全部接受完畢
{
RB1=1;
i=0;
if((RX[0]==66)&&(RX[6]==88)) //校驗(yàn)傳輸字符正確性
{
CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
}
ADCON0=0x85;//開(kāi)啟轉(zhuǎn)換
}
ADCON0=0x85;//開(kāi)啟轉(zhuǎn)換
;
;
}
}
終極版本出爐!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//***********************************************************
//-------------- 源文件名為:rs232sample1.c-----
//最簡(jiǎn)單的程序框架
//RB口輸出程序執(zhí)行標(biāo)簽
//將通道0的模擬量對(duì)其進(jìn)行AD轉(zhuǎn)換其值送至串口輸出
//將串口上位機(jī)設(shè)定的值送給PWM輸出,
//******************************************
#include
#include
__CONFIG(XT & WDTDIS& PWRTDIS & BORDIS & PROTECT );//配置字
void DELAY(int time);
void initPORTB();
void initPORTA();
void initPORTC();
void inittmr2();
void initCCP1();
//變量定義
unsigned char recdata,RX[8],i,j,k,t; //0-255
unsigned char TX[8]={0x42,0x72,0x55,0x30,0x30,0x30,0x46,0x50};//BrU000FP
int AD_result;
//------------------初始化 PORTB--------
void initPORTB()
{ TRISB=0xe0; //設(shè)置portb口高3位為輸入,低5位為輸出
RBIE=0; //關(guān)閉B口的中斷
PORTB=0x00; //RB口先送低電平清除干擾
}
//-----------------初始化 PORTA----------
void initPORTA() //包含AD轉(zhuǎn)換初始化
{ TRISA=0x3f; //設(shè)置portA口 輸入
ADCON1=0x00; //A口全為AD口,RA0,1,2,3,5為模擬口,考電壓VDD
ADCON0=0x85; //fosc/32,通道0-85,89-chanl1,開(kāi)啟轉(zhuǎn)換
ADIE=1; //允許中斷
}
//------------------初始化 PORTC--------
void initPORTC() //包含波特率設(shè)置
{ TRISC=0xC0; //設(shè)置portC口狀態(tài),RC7/RX為輸入
TXSTA=0XA6;
RCSTA=0XB0; //使能串口,8位連續(xù)接收,B0連續(xù)接受
PIR1=0X00; //
RCIE=1; //接受中斷
TXIE=1; //發(fā)送中斷
PORTC=0x00; //RC口賦初值
SPBRG=25; //9600-25(10進(jìn)制)
}
//---------------初始化 tmr2------------------
void inittmr2()
{ TMR2 =0; //賦初值,
T2CON=0x72; //0x72后分頻為1:8,預(yù)分頻為1:16,先關(guān)閉.,31-4后分頻,4預(yù)分頻
// TMR2IE=1; //開(kāi)/關(guān)定時(shí)器2中斷,清標(biāo)志位
TMR2IF=0;
TMR2ON=1; //啟動(dòng)定時(shí)器2
}
//---------------初始化 CCP1 ------------------
void initCCP1()
{
CCP1IF=0; //清標(biāo)志位
CCP1CON=0X0c; //設(shè)置工作模式
//Pwm模式
CCP1IE=0; //關(guān)閉中斷
PR2=0XFF; //定時(shí)器2的最大周期 245hZ
CCPR1L=0X0f; //預(yù)制一個(gè)數(shù)
CCPR1H=0; //,通過(guò)改變CCPR1L的值即可實(shí)現(xiàn)占空比的改變
}
void interrupt all_int()
{
//首先判斷中斷的類(lèi)型,執(zhí)行不同的中斷子程序
//中斷優(yōu)先級(jí)依次為接收中斷、AD轉(zhuǎn)換中斷、發(fā)送中斷
if(RCIF&&RCIE) //判斷是否是串口接收中斷
{
// RB1=1;
RCIF=0;//清干擾
recdata=RCREG; // 接收數(shù)據(jù)并存儲(chǔ)
RX[i]=recdata;
i=i+1;
if(i>=8)//全部接受完畢
{
RB4=1;
i=0;
if((RX[0]==66)&&(RX[6]==88)) //校驗(yàn)傳輸字符正確性
{
CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
if(CCPR1L==0)
{
RB4=0;
}
}
}
}
//------AD轉(zhuǎn)換中斷----
if(ADIF&&ADIE)
{
ADIF=0;//清干擾
RB2=1;
t=t+1;
AD_result=AD_result+ADRES;
if (t==16)
{
t=0;
AD_result=AD_result>>4;
TX[3]=(AD_result/100)+48;
TX[4]=((AD_result%100-AD_result%10)/10)+48;
TX[5]=(AD_result%10)+48;
AD_result=0;
}
ADCON0=0x85;
}
//-------發(fā)送中斷-----
if(TXIF&&TXIE)
{
TXREG=TX[j];
RB3=1;
j=j+1;
if(j>=8)
{j=0;}
}
}
//軟件延時(shí)子程序
void DELAY(int time)
{
int x,y;
for(x=0;x<50;x++)
{
for(y=0;y }
}
//--------------------主程序------------------------
main()
{
initPORTB(); //PORTB初始化
initPORTA(); //PORTA初始化
initPORTC(); //PORTC初始化
inittmr2();
initCCP1();
GIE=1;
PEIE=1;
AD_result=0;
while(1)
{
RB1=1;
DELAY(10);
ADCON0=0x85;
}
}
評(píng)論