程式如下: 串口1接收發送都可以使用,串口2發送測驗也是可以用的,現在問題就是卡在接收上,接收有問題
麻煩論壇大神幫忙看看串口2接收哪里有問題,萬分感謝!!!
/***********************************************************************
時間:2020.04.04
芯片:STC12C5A60S2
晶振:11.0592MHz 波特率:115200bps
引腳定義:串行口1: 發送————TxD/P3.1; 接收————RxD/P3.0
串行口2: 發送————TxD2/P1.3;接收————RxD2/P1.2
功能描述:STC12雙串口通信(中斷方式)
當串行口1接收資料后,將此資料由串行口2發送出去
當串行口2接收資料后,將此資料由串行口1發送出去
***********************************************************************/
#include<STC12C5A60S2.h>
#include "intrins.h"
#include "string.h"
#include "stdio.h"
#define S2RI 0x01 //串口2接收中斷請求標志位
#define S2TI 0x02 //串口2發送中斷請求標志位
#define uchar unsigned char
#define uint unsigned int
#define S2RI 0x01
#define S2TI 0x02
#define Code_head1 0xAA
#define Code_head2 0x55
#define len 25
bit busy2; //此位用于串口判斷是否發送繁忙
char xdata Uart2_buff[40]; //緩沖資料
char xdata Uart1_buff[40];
uchar count2=0; //串口計數器
uchar count1=0; //串口計數器
char xdata echo[40];
unsigned char flag1,flag2,temp1,temp2;
void Clear_Buff(); //清除串口1,2中陣列的值,為下一次做準備
void read_code2(uchar _char); //保存串口接收到的字符
void Uart_1_SendString(char *P); //串口1 發送字串函式
float TDM_Receive_Check();
void set_brrate();
void serial_put_uint(unsigned int number);
void dispplay(int _data);
void read_ac();
void read_once();
void delay_ms(uint ms);
/****************串行口初始化函式****************/
void InitUART(void)
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位資料,可變波特率
AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時器1為波特率發生器
TMOD &= 0x0F; //清除定時器1模式位
TMOD |= 0x20; //設定定時器1為8位自動重裝方式
TL1 = 0xFD; //設定定時初值
TH1 = 0xFD; //設定定時器重裝值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
/****************************115200******************************/
AUXR &= 0xF7; //波特率不倍速
S2CON = 0x50; //8位資料,可變波特率
AUXR |= 0x04; //獨立波特率發生器時鐘為Fosc,即1T
BRT = 0xFD; //設定獨立波特率發生器重裝值
AUXR |= 0x10; //啟動獨立波特率發生器
IE2=0x01;//允許串口2中斷。
EA=1;//總中斷一定要開,不然能發送,不能接收
}
/****************串行口1發送****************/
void UART_1SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI); //若TI=0,在此等待
TI = 0;
}
/****************串行口2發送****************/
void UART_2SendOneByte(unsigned char c)
{
S2BUF = c;
while(!(S2CON&S2TI)); //若S2TI=0,在此等待
S2CON&=~S2TI; //S2TI=0
}
/*****************主函式******************/
void main(void)
{
InitUART(); //串行口初始化
Uart_1_SendString("*****************************\r\n");
Uart_1_SendString("************00000***********\r\n");
while(1)
{
int i;
//如果串口1接收到資料,將此資料由串口2發送
if(flag1==1)
{
flag1=0;
for(i=0; i<sizeof(Uart1_buff); i++)
{
UART_1SendOneByte(Uart1_buff[i]);
}
read_ac();
Uart_1_SendString("\r\n");
Clear_Buff();
}
//如果串口2接收到資料,將此資料由串口1發送
if(flag2==1)
{
flag2=0;
UART_1SendOneByte(temp2);
}
}
}
/************串行口1中斷處理函式*************/
void UART_1Interrupt(void) interrupt 4 using 3
{
if(RI)
{
RI=0;
ES=0;//關掉串口總中斷。
Uart1_buff[count1]=SBUF;
switch(Uart1_buff[count1])
{
case '\r':
flag1=1;
count1=0;
ES=0;
REN=0;
break;
case '\n':
flag1=1;
count1=0;
ES=0;
REN=0;
break;
default:
count1++;
}
ES=1;//再開串口中斷。
}
}
/************串行口2中斷處理函式*************/
void UART_2Interrupt(void) interrupt 8 using 2
{
if(S2CON & S2RI)//判斷是否有接收中斷。
{
S2CON &= 0xFE;//清除串口2接收中斷。
ES=0;//關掉串口總中斷。
Uart2_buff[count2]=S2BUF;
count2++;
ES=1;//再開串口中斷。
}
}
/*----------------------------
串口1發送函式:
引數: 字串
回傳值: None
----------------------------*/
void Uart_1_SendString(char *P)
{
ES = 0;
REN=0;
while(*P!='\0') //只要*P不為空,就一直發送
{
SBUF=*P;
P++;
while(!TI);
TI=0;
}
REN=1;
ES = 1;
}
/****************讀取一次結果********************/
void read_ac()
{
int current = 0;
int i;
Clear_Buff();//清除串口1,2緩沖
read_once(); //讀取單次資料
delay_ms(10);
// for(i=0;i<sizeof(Uart2_buff);i++) 這里我把串口2接收到的資料通過串口1發送,但是沒有資料
// {
// UART_1SendOneByte(Uart2_buff[i]);
// UART_1SendOneByte('\n');
// UART_1SendOneByte('*');
// }
sprintf(echo,"DC:%.1f mA",TDM_Receive_Check());
Uart_1_SendString(echo);
Clear_Buff();//清除串口緩沖
}
/****************讀取電流表函式********************/
void read_once()
{
uint Sum_check = 0;
Sum_check = 0xfe + 0x02;
UART_2SendOneByte(Code_head1);
UART_2SendOneByte(Code_head2);
UART_2SendOneByte(0x02);
UART_2SendOneByte(0xFE);
UART_2SendOneByte(0x01);
UART_2SendOneByte(0x00);
}
/*
*格式化列印給上位機函式,輸入是十六進制電流值,輸出串口字串
*/
void dispplay(int _data)
{
int temp;
temp = _data;
if (temp == 0x8000)//判斷是否是超量程,表的PDF檔有介紹
{
Uart_1_SendString("OL");
}
else
{
if (temp < 0)
{
Uart_1_SendString("-");//輸出負號
temp *= -1;//變成正值
}
serial_put_uint(temp);
}
}
/*
*對串口2接收到的資料進行檢查如果校驗位OK,回傳讀出的電流值
*/
float TDM_Receive_Check()
{
float value;
if((Uart2_buff[0]==0xAA)&&(Uart2_buff[1]==0x55)&&(Uart2_buff[2]==0x04)&&(Uart2_buff[3]==0xF6))
{
if(( Uart2_buff[6]*256+Uart2_buff[7])==(Uart2_buff[2]+Uart2_buff[3]+Uart2_buff[4]+Uart2_buff[5]))
{
value =(((Uart2_buff[5]<<8)+(Uart2_buff[4])));//mA檔中。
return value; //如果接收校驗OK回傳讀出來的值。
}
}
else
{
return 0x8888;//十進制:34952
}
}
/*************清除串口1,2陣列*****************/
void Clear_Buff()
{
int i;
for(i=0; i<sizeof(Uart2_buff); i++)
{
Uart2_buff[i]=0;
}
for(i=0; i<sizeof(Uart1_buff); i++)
{
Uart1_buff[i]=0;
}
}
void delay_ms(uint ms)
{
int i;
for(i=0; i<ms; i++)
{
_nop_();
}
}
uj5u.com熱心網友回復:
count1++;
count2++;沒加限制會有溢位風險
其他沒看出什么
uj5u.com熱心網友回復:
找人寫程式 硬體是stc12c5024ad 硬體都做好了 用22.1184的晶振 用2片hc244 做12路輸入 一個64位的撥碼開關做地址輸入 4片tpic6b595做2組輸出 一個485和西門子plc200做通信用 plc的程式寫好了 實作12路乘n地址的輸入的計數 報警 顯示 的QQ39084813
uj5u.com熱心網友回復:
在串口2接收中斷中 flag2 沒有賦值。主程式中判斷 flag2 就會沒收到數。你沒仿真器嗎?用仿真器在中斷中下個斷點,很容易就跟出毛病了。
uj5u.com熱心網友回復:
清中斷標志位了沒轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/33831.html
標籤:單片機/工控
上一篇:JavaScript面向物件編程
