基于PIC16F73的下位機串口通訊設計備忘
基本功能要求:
本文引用地址:http://www.ex-cimer.com/article/201608/296034.htm接收上位機所給的設定命令,并根據命令進行相應的操作,同時下位機將采集到的信息上傳給上位機處理顯示等。
具體細節(jié)設計:
由于本設計主要針對本公司的高壓電源的,關于采集到的輸出高壓反饋值的模擬量可以利用單片機內部集成的8位AD轉換模塊,
而電源的設定電壓采用單片機內部的PWM模塊來實現8位的DA轉換,
具體程序如下:(初稿)
//***********************************************************
//-------------- 源文件名為:RS232.c-----
//監(jiān)控高壓源71520的工作,開啟高壓,上位機可以設定高壓值
//同時可以監(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; //設置portb口高3位為輸入,低5位為輸出
RBIE=1; //關閉B口的中斷
PORTB=0x00; //RB口先送高電平清除干擾
}
//-----------------初始化 PORTA----------
void initPORTA() //包含AD轉換初始化
{ TRISA=0x3f; //設置portA口 輸入
ADCON1=0x00; //A口全為AD口,RA0,1,2,3,5為模擬口,考電壓VDD
ADCON0=0x85; //fosc/32,通道0-85,8D-chanl1,開啟轉換
ADIE=1; //允許中斷
}
//------------------初始化 PORTC--------
void initPORTC() //包含波特率設置
{ TRISC=0xC0; //設置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進制)
}
//---------------初始化 tmr2------------------
void inittmr2()
{ TMR2 =0; //賦初值,
T2CON=0x72; //0x72后分頻為1:8,預分頻為1:16,先關閉.,31-4后分頻,4預分頻
// TMR2IE=1; //開/關定時器2中斷,清標志位
TMR2IF=0;
TMR2ON=1; //啟動定時器2
}
//---------------初始化 CCP1 ------------------
void initCCP1()
{
CCP1IF=0; //清標志位
CCP1CON=0X0c; //設置工作模式
//Pwm模式
CCP1IE=1; //關閉中斷
PR2=0XFF; //定時器2的最大周期 245hZ
CCPR1L=0X0f; //預制一個數
CCPR1H=0; //,通過改變CCPR1L的值即可實現占空比的改變
}
void interrupt all_int()
{
//首先判斷中斷的類型,執(zhí)行不同的中斷子程序
//中斷優(yōu)先級依次為接收中斷、AD轉換中斷、發(fā)送中斷
if(RCIF&&RCIE) //判斷是否是串口接收中斷
{
// RB1=1;
RCIF=0;//清干擾
recdata=RCREG; // 接收數據并存儲
RX[i]=recdata;
i=i+1;
}
//------AD轉換中斷----
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;}
}
}
//軟件延時子程序
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; //開啟外圍中斷
RB2=0;
RB1=0;
RB3=0;
k=56;
while(1)
{
//---------取出AD轉換的百位、十位、個位-----
if(k==55)
{
RB4=1;
ADIE=0;//數據傳輸期間禁止更改
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;//開啟轉換
}
if(i>=8)//全部接受完畢
{
RB1=1;
i=0;
if((RX[0]==66)&&(RX[6]==88)) //校驗傳輸字符正確性
{
CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
}
ADCON0=0x85;//開啟轉換
}
ADCON0=0x85;//開啟轉換
;
;
}
}
終極版本出爐!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//***********************************************************
//-------------- 源文件名為:rs232sample1.c-----
//最簡單的程序框架
//RB口輸出程序執(zhí)行標簽
//將通道0的模擬量對其進行AD轉換其值送至串口輸出
//將串口上位機設定的值送給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; //設置portb口高3位為輸入,低5位為輸出
RBIE=0; //關閉B口的中斷
PORTB=0x00; //RB口先送低電平清除干擾
}
//-----------------初始化 PORTA----------
void initPORTA() //包含AD轉換初始化
{ TRISA=0x3f; //設置portA口 輸入
ADCON1=0x00; //A口全為AD口,RA0,1,2,3,5為模擬口,考電壓VDD
ADCON0=0x85; //fosc/32,通道0-85,89-chanl1,開啟轉換
ADIE=1; //允許中斷
}
//------------------初始化 PORTC--------
void initPORTC() //包含波特率設置
{ TRISC=0xC0; //設置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進制)
}
//---------------初始化 tmr2------------------
void inittmr2()
{ TMR2 =0; //賦初值,
T2CON=0x72; //0x72后分頻為1:8,預分頻為1:16,先關閉.,31-4后分頻,4預分頻
// TMR2IE=1; //開/關定時器2中斷,清標志位
TMR2IF=0;
TMR2ON=1; //啟動定時器2
}
//---------------初始化 CCP1 ------------------
void initCCP1()
{
CCP1IF=0; //清標志位
CCP1CON=0X0c; //設置工作模式
//Pwm模式
CCP1IE=0; //關閉中斷
PR2=0XFF; //定時器2的最大周期 245hZ
CCPR1L=0X0f; //預制一個數
CCPR1H=0; //,通過改變CCPR1L的值即可實現占空比的改變
}
void interrupt all_int()
{
//首先判斷中斷的類型,執(zhí)行不同的中斷子程序
//中斷優(yōu)先級依次為接收中斷、AD轉換中斷、發(fā)送中斷
if(RCIF&&RCIE) //判斷是否是串口接收中斷
{
// RB1=1;
RCIF=0;//清干擾
recdata=RCREG; // 接收數據并存儲
RX[i]=recdata;
i=i+1;
if(i>=8)//全部接受完畢
{
RB4=1;
i=0;
if((RX[0]==66)&&(RX[6]==88)) //校驗傳輸字符正確性
{
CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
if(CCPR1L==0)
{
RB4=0;
}
}
}
}
//------AD轉換中斷----
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;}
}
}
//軟件延時子程序
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;
}
}
評論