技术热线: 4007-888-234

PIC单片机C语言编程实例四

更新时间: 2019-01-05
阅读量:2535

通用同步/异步通信的应用
8.5 单片机双机异步通信
1 单片机PIC1编程(发送部分)

include

/该程序实现单片机双机异步通信功能,该程序是发送部分/
unsigned char tran[8]; /定义一个数组存储发送数据/
unsigned char k,data; /定义通用寄存器/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/不带小数点的显示段码表/
/spi显示初始化子程序/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
/设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送,与”74HC595,当其 SCLK从低到高跳变时,串行输入寄存器”的特点相对应/
TRISC=0xD7; /
SDO引脚为输出,SCK引脚为输出/
TRISA5=0; /
RA5引脚设置为输出,以输出显示锁存信号/
}
/
给数组赋初值子程序 /
void fuzhi()
{
for(k=0;k<8;k++) {
tran[k]=k+3;
}
}
/
SCI部件初始化子程序/
void sciint()
{
SPBRG=0X19; /
将传输的波特率设为约9 600位/秒/
TXSTA=0X04; /
选择异步高速方式传输8位数据/
RCSTA=0X80; /
允许同步串行口工作/
TRISC6=1;
TRISC7=1; /
将RC6、RC7设置为输入方式,对外部呈高阻状态/
}
/
SPI传输数据子程序/
void SPILED(data)
{
SSPBUF=data; /
启动发送/
do {

}while(SSPIF==0);
SSPIF=0;
}
/
显示子程序,显示8位数/
void display()
{
RA5=0; /
准备锁存/
for(k=0;k<8;k++) {
data=tran[k];
data=table[data]; /
查得显示的段码/
SPILED(data); /
发送显示段码/
}
RA5=1; /
最后给一个锁存信号,代表显示任务完成/
}
/
主程序/
main()
{
SPIINIT();
fuzhi(); /
给数组赋初值/
sciint(); /
SCI部件初始化/
di(); /
中断禁止/
TXEN=1; /
发送允许/
CREN=1; /
接收数据允许/
for(k=0;k<8;k++){
TXREG=tran[k]; /
发出一个字符/
while(1){
if(TXIF==1) break;
} /
等待写入完成/
while(1){
if(RCIF==1) break;/
若收到响应字节,则终止等待/
}
RCREG=RCREG; /
读响应字节,清RCIF/
}
display(); /
显示发送的数据*/
while(1){

}
}

2 单片机PIC2编程(接收部分)

include

/该程序实现单片机双机异步通信功能,该程序是接收部分,并把接收的数据显示在8 个LED上/
unsigned char rece[8];/
定义一个数组存储接收数据/
unsigned char k,data;/
定义通用寄存器/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/
不带小数点的显示段码表/
/
spi显示初始化子程序/
void SPIINIT()
{
;详细语句见发送程序
}
/
SCI部件初始化子程序/
void sciint()
{
SPBRG=0X19; /
波特率设置与PIC1相同,为约9 600位/秒/
TXSTA=0X04; /
异步高速传输/
RCSTA=0X80; /
串行口工作使能/
TRISC6=1;
TRISC7=1; /
将RC6、RC7设置为输入方式,对外部呈高阻状态/
}
/
SPI传送数据子程序/
void SPILED(data)
{
;详细语句与见发送程序
}
/
显示子程序,显示4位数/
void display()
{
RA5=0; /
准备锁存/
for(k=0;k<8;k++){
data=rece[k];
data=table[data]; /
查得显示的段码/
SPILED(data); /
发送显示段码/
}
RA5=1; /
最后给一个锁存信号,代表显示任务完成/
}
/
主程序/
main()
{
SPIINIT(); /
spi显示初始化/
sciint(); /
SCI部件初始化/
di(); /
中断禁止/
CREN=1; /
接收允许/
TXEN=1; /
发送允许/
for(k=0;k<8;k++){
while(1){
if(RCIF==1) break;
} /
等待接收数据/
rece[k]=RCREG; /
读取接收数据,同时清掉RCIF/
TXREG=rece[k]; /
发送接收到的数据/
while(1){
if(TXIF==1) break;
} /
等待写入完成/
}
display(); /
显示接收的数据*/
while(1){

}
}
8.6 单片机双机同步通信
1 单片机PIC1编程(主控发送)

include

/该程序实现单片机双机同步通信功能,是主控发送部分。程序上电后显示 相应的字符,表示系统正常工作。发送完毕后显示发送的数据/
unsigned char tran[8]; /
定义一个数组存储发送数据/
unsigned char k,data; /
定义通用寄存器/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/
不带小数点的的显示段码表/
/
spi显示初始化子程序/
void SPIINIT()
{
;详细程序语句请参考本章8.5节
}
/
给发送数组赋初值子程序 /
void fuzhi()
{
for(k=0;k<8;k++){
tran[k]=k;
} /
发送0~7八个数据/
}
/
SCI部件初始化子程序/
void sciint()
{
SPBRG=200 ; /
将传输的波特率设为约9600位/秒/
TXSTA=0X90; /
选择主控方式/
RCSTA=0X80; /
允许同步串行口工作/
TRISC6=1;
TRISC7=1; /
将RC6、RC7设置为输入方式,对外部呈高阻状态/
}
/
SPI传送数据子程序/
void SPILED(data)
{
;详细程序语句请参考本章8.5节
}
/
显示子程序,显示8位数/
void display()
{
RA5=0; /
准备锁存/
for(k=0;k<8;k++){
data=tran[k];
data=table[data]; /
查得显示的段码/
SPILED(data); /
发送显示段码/
}
RA5=1; /
最后给一个锁存信号,代表显示任务完成/
}
/
显示子程序,显示8位数/
void display1()
{
RA5=0; /
准备锁存/
for(k=0;k<8;k++){
data=0xf9; /
显示”1”表示系统正常工作/
SPILED(data); /
发送显示段码/
}
RA5=1; /
最后给一个锁存信号,代表显示任务完成/
}
/
主程序/
main()
{
SPIINIT(); /
spi显示初始化/
fuzhi(); /
给发送数组赋发送初值/
sciint(); /
SCI部件初始化/
di(); /
中断禁止/
TXEN=1; /
发送允许/
display1(); /
显示相应的字符,表示系统正常/
while(1){
for(k=0;k<8;k++){
TXREG=tran[k];/
发出一个字符/
while(1){
if(TXIF==1) break;
} /
等待上一个数据写入完成/
}
display(); /
显示发送的数据/
} /
循环发送*/
}

2 单片机PIC2编程(从动接收)

include

/该程序实现单片机双机 同步通信功能,是从动接收部分,并把接收的数据显 示在8个LED上/
unsigned char rece[8]; /
定义一个数组存储接收数据/
unsigned char k,data; /
定义通用寄存器/
unsigned int i;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/
不带小数点的显示段码表/
/
spi显示初始化子程序/
void SPIINIT()
{
;详细程序语句请参考本章8.5节
}
/
SCI部件初始化子程序/
void sciint()
{
TXSTA=0X10 ; /
选择同步从动方式/
RCSTA=0X90; /
串行口工作使能/
TRISC6=1;
TRISC7=1; /
将RC6、RC7设置为输入方式对外部呈高阻状态/
}
/
SPI传送数据子程序/
void SPILED(data)
{
;/
详细程序语句请参考本章8.5节/
}
/
显示子程序,显示4位数/
void display()
{
RA5=0; /
准备锁存/
for(k=0;k<8;k++){
data=rece[k];
data=table[data]; /
查得显示的段码/
SPILED(data); /
发送显示段码/
}
RA5=1; /
最后给一个锁存信号,代表显示任务完成/
}
/
主程序/
main()
{
SPIINIT(); /
spi显示初始化/
sciint(); /
SCI部件初始化/
di(); /
中断禁止/
CREN=1; /
接收允许/
for(k=0;k<8;k++) rece[k]=0x03;
display(); /
显示表示系统正常运行的数据/
while(1) {
while(1){
CREN=1; /
允许连续接收/
while(1){
if(RCIF==1) break;
} /
等待接收数据/
k=0;
rece[k]=RCREG; /
读取接收数据/
if(OERR==1) { /
如果有溢出错误,则处理/
CREN=0;
CREN=1;
}
if(rece[k]==0x00) break;/
“0”为同步字符,只有接收到“0”时才进行下面的接收/
}
for(k=1;k<8;k++){
while(1){
if(RCIF==1) break;
} /
等待接收数据/
rece[k]=RCREG;/
读取接收数据/
if(OERR==1) { /
如果有溢出错误,则处理/
CREN=0;
CREN=1;
}
rece[k]=rece[k]&0x0F;/
屏蔽掉高位,防止干扰/
}
CREN=0;
display(); /
显示接收的数据/
for(i=65535;—i; )continue;
for(i=65535;—i; )continue;/
给予一定时间的延时,再进行下一轮接收*/
}
}

8.7 单片机与PC机通信
1 PC机编程
PC采用Toubr C 进行编写。程序如下:

include

define port 0x3f8 /利用串口1进行通信/

int ch[15];
main ()
{
int a;
int i,j;
int b[6]={88,15,38,26,20,0};
char c;
clrscr();
outportb(port+3,0x80); /准备设置波特率/
outportb(port,0x0C); /波特率设置为9600bps/
outportb(port+1,0x00);
outportb(port+3,0x03); /8位数据,无奇偶检验,1位停止位/
outportb(port+1,0x00); /关中断/
inportb(port+5); /读一次线路状态寄存器,使其复位/
for(;;){
printf(“\t\tsend data or receive data: (s or r?)\n\n\n”);
c=getchar();
switch(c) {
case ‘s’:
case ‘S’: {
while(!(inportb(port+5)&0x20));/发送保持器满则等待/
outportb(port,0x01); /否则发送数据01,通知单片机准备接收/
for(i=0;i<6;i++){ /共发送6个数据/
a=b[i];
while(!(inportb(port+5)&0x20)) delay(100);/发送保持器满,等待/
outportb(port,a); /发送a/
printf(“%d\n”,a); /显示a/
while(!(inport(port+5)&1)); /接收单片机送回的数据/
ch[i]=inport(port); /保存/
}
delay(10);
for(j=0;j<8;j++) printf(“\n%d\n”,ch[j]);/显示接收的回送数据/
getch();
break;
}
case’r’: /接收数据/
case’R’:{
while(!(inportb(port+5)&0x20));
outportb(port,0x02); /发送数据02,通知单片机发送数据/
for(j=0;j<9;j++) { /共接收9个数据/
while(!(inportb(port+5)&1));
ch[j]=inportb(port);
}
for(j=0;j<9;j++) printf(“\n %d\n”,ch[j]);
getch();
break;
}
}
}
}