51单片机 HC05串口通信写好了 不知道怎么加进去 大神救救孩子吧

sixto47 2018-11-21 04:08:21
写了个独立的串口通信程序,是能正常收发的,可是怎么加进整个程序,没有思路啊。。。整了两天,都不对

波特率9600 晶振12M

单独的串口通信程序:
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;

void UsartInit()
{
SCON=0X50;
TMOD=0X20;


PCON=0X80;
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
EA=1;
ES=1;
TR1=1;
}
void main()
{
UsartInit();
while(1);
}
void Usart() interrupt 4
{
u8 rec;
rec=SBUF;
RI = 0;
SBUF=rec;
while(!TI);
TI=0;
}


整个程序:
void main(void)
{
Delay_1ms(100);
LCD_Init();
TimerInit();
PageInit();
DataLoad();

while(1)
{
ModeDisplay(); //模式切换
Delay_1ms(100);
DS1302_Read(); //时间读取
PageDisplay(); //写入
Delay_1ms(500); //页面显示
GetTemp(); //温度读取
GetLight(); //获取光强
TimeControl(); //时间控制
TempLightControl(); //温度光强控制
LanControl();
Delay_1ms(20);
WrToROM(CloseTime,5,3);
Delay_1ms(20);
WrToROM(OpenTime,0,3);
Delay_1ms(20);
LCD_Refresh();
Delay_1ms(20); //延时
}
}


void Timer_ISR(void) interrupt 1
{
TH0 = (65536-21000)/256;
TL0 = (65536-21000)%256;
KEY_Scan();
if(AlarmCon>0)
{
AlarmCon++;
if(AlarmCon>=5)
{
AlarmCon=0;
BUZZER=1;
}
}
/*-------------------------------------*/
if(Mode==1)
{
if(IR_Delay>0)
{
IR_Delay--;
}
else
{
Y_RunFlag=0;
}
if(Mode==1&&KEY2==0)
{Delay_1ms(10);
Y_RunFlag=1;
Delay_1ms(10);
KEY2=1;}
else if (Mode==1&&KEY3==0)
{Delay_1ms(10);
Y_RunFlag=2;
Delay_1ms(10);
KEY3=1;}
}


}


void Timer1_ISR(void) interrupt 3
{

static uchar ycon=0;
TH1 =(65535-1100)/256;
TL1 =(65535-1100)%256;
if(Y_RunFlag==1)
{
if(Step<SetStep)
{
Step++;
P2= P2&0xf0 | Zheng[ycon];
ycon++;
if(ycon>7)
ycon=0;
}
else
{
Y_RunFlag=0;
BUZZER=0;
AlarmCon=1;
}
}
else if(Y_RunFlag==2)
{
if(Step>0)
{
Step--;
P2= P2&0xf0 | Fan[ycon];
ycon++;
if(ycon>7)
ycon=0;
}
else
{
Y_RunFlag=0;
BUZZER=0;
AlarmCon=1;
}
}
else
{
P2= P2&0xf0;
}

}

void LanControl(void) //蓝牙控制程序
{
if(Mode==1) {

switch (rec)
{
case '1': Y_RunFlag=1;break; //正转
case '2': Y_RunFlag=2;break; //反转
case '3': Y_RunFlag=0;break; //停止
default:break;
}
Delay_1ms(100);
}
}


void LanControl_Int(void) interrupt 0 //接收串口中断
{
u8 rec;
rec=SBUF;
RI = 0; //清除接收中断标志位
SBUF=rec; //将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}


void TimerInit(void)
{
TMOD = 0x11;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
ET0 = 1;
TR0 = 1;
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
ET1 = 1;
TR1 = 1;
EA = 1;
}

大神,该怎么改才合适
...全文
548 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
sixto47 2018-11-23
  • 打赏
  • 举报
回复
引用 19 楼 笨狗先飞 的回复:
好象有独立的波特率发生器,那样,你时钟就独立可以用了。

搞定了谢谢您,之前一直以为是串口通信程序出了问题,其实不是,是LCD初始化程序在干扰。
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 13 楼 xws245925587 的回复:
[quote=引用 12 楼 sixto47 的回复:]
[quote=引用 11 楼 xws245925587 的回复:]
[quote=引用 10 楼 sixto47 的回复:]
[quote=引用 9 楼 xws245925587 的回复:]
[quote=引用 7 楼 sixto47 的回复:]
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大[/quote]
这样太麻烦了吧,而且我写的单独的那个串口通信程序是可以接收的,但不知道为什么加到完整程序进去之后,竟然接收不了[/quote]
现在因为主程序中用了定时器1,然后串口波特率也是用定时器1生成的,所以,用那个独立波特率发射器配置波特率,就是改串口初始化那里的程序[/quote]

您有具体的程序吗,没搞过这样的诶[/quote]

查下STC12的单片机数据手册,那里有例程,网上有挺多资料的,我现在手头没有[/quote]
#include
char flag;
sfr AUXR= 0x8E;
sfr BRT = 0xfd;//0xfd是9600;

void UsartInit(void) {
AUXR=0x11;//独立波特率发生运行,使用独立波特率为串口1的波特率发生器
BRT=0xFD;//重载值11059200,12T重装值是0xfd;
SM0=0;
SM1=1;
REN=1;
flag=0;

void Usat(void){
if(RI)
{
RI=0;
rec=SBUF;
if(rec==0x11)
{
flag=1;
}

}

if(flag==1)
{
TI=0;
flag=0;
SBUF=rec;
}
}

写了这个进去,还是不行,是我的重装初值不对吗?
您要是有空帮我看看那些值是不是不对(12M 9600波特率)
xws245925587 2018-11-22
  • 打赏
  • 举报
回复
引用 12 楼 sixto47 的回复:
[quote=引用 11 楼 xws245925587 的回复:]
[quote=引用 10 楼 sixto47 的回复:]
[quote=引用 9 楼 xws245925587 的回复:]
[quote=引用 7 楼 sixto47 的回复:]
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大[/quote]
这样太麻烦了吧,而且我写的单独的那个串口通信程序是可以接收的,但不知道为什么加到完整程序进去之后,竟然接收不了[/quote]
现在因为主程序中用了定时器1,然后串口波特率也是用定时器1生成的,所以,用那个独立波特率发射器配置波特率,就是改串口初始化那里的程序[/quote]

您有具体的程序吗,没搞过这样的诶[/quote]

查下STC12的单片机数据手册,那里有例程,网上有挺多资料的,我现在手头没有
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 11 楼 xws245925587 的回复:
[quote=引用 10 楼 sixto47 的回复:]
[quote=引用 9 楼 xws245925587 的回复:]
[quote=引用 7 楼 sixto47 的回复:]
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大[/quote]
这样太麻烦了吧,而且我写的单独的那个串口通信程序是可以接收的,但不知道为什么加到完整程序进去之后,竟然接收不了[/quote]
现在因为主程序中用了定时器1,然后串口波特率也是用定时器1生成的,所以,用那个独立波特率发射器配置波特率,就是改串口初始化那里的程序[/quote]

您有具体的程序吗,没搞过这样的诶
xws245925587 2018-11-22
  • 打赏
  • 举报
回复
引用 10 楼 sixto47 的回复:
[quote=引用 9 楼 xws245925587 的回复:]
[quote=引用 7 楼 sixto47 的回复:]
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大[/quote]
这样太麻烦了吧,而且我写的单独的那个串口通信程序是可以接收的,但不知道为什么加到完整程序进去之后,竟然接收不了[/quote]
现在因为主程序中用了定时器1,然后串口波特率也是用定时器1生成的,所以,用那个独立波特率发射器配置波特率,就是改串口初始化那里的程序
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 9 楼 xws245925587 的回复:
[quote=引用 7 楼 sixto47 的回复:]
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大[/quote]
这样太麻烦了吧,而且我写的单独的那个串口通信程序是可以接收的,但不知道为什么加到完整程序进去之后,竟然接收不了
xws245925587 2018-11-22
  • 打赏
  • 举报
回复
引用 7 楼 sixto47 的回复:
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
另外,如果要配置9600波特率的话,晶振换成11.0592的,12M配置不出来9600波特率,误差太大
xws245925587 2018-11-22
  • 打赏
  • 举报
回复
引用 7 楼 sixto47 的回复:
[quote=引用 5 楼 xws245925587 的回复:]
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施[/quote]
用12的话,有独立波特率发射器,设置好久可以了
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 5 楼 xws245925587 的回复:
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了

我用的是5A60s2 那这样的话,您的解决方法具体是怎么实施
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 4 楼 bakw 的回复:
[quote=引用 3 楼 sixto47 的回复:]
[quote=引用 2 楼 bakw 的回复:]
main函数初始化的时候把UsartInit(); 也加进去不就好了?
收到的信息反正都是在中断里处理的,收一字节存一字节,存到一个数组的缓冲区里。
设置一个全局标志位,数据接收的差不多了,就在中断里标记一下标志位,
主循环里判断一下,有接收标志位了,就去把缓冲区里的数据读过来,处理,该操作的操作,该发送的发送。


那我的TimerInit()里TMOD不会冲突吗,也写过,发现Interrupt 3 的失效了[/quote]
有些单片机串口是需要占用时钟的记得一般是T1吧,有些单片机有波特率发生器,避开串口需要占用的时钟

你的 UsartInit() 里用的 TMOD 是 0x20 ,占用第五位,
TimerInit() 里是0x11,占用第零位和第四位,
你写的时候用 TMOD|=0x20 ,TMOD|=0x11这样来写,置位的时候就不会把之前的设定去掉了。
单片机里设置一个位一般都是 XXX|=xx来写1,需要写0用 XXX&=~xx来写某位的0[/quote]
那TH1 TL1 只初始化一遍就可以了吧?
xws245925587 2018-11-22
  • 打赏
  • 举报
回复
看你主程序,使用了定时器1中断处理一些事情,如果用的是52的单片机,串口波特率初始化用定时器2,然后把串口初始化加进主程序while前,中断函数也写好,就可以了
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 19 楼 笨狗先飞 的回复:
好象有独立的波特率发生器,那样,你时钟就独立可以用了。

排查出来了是LCD初始化程序出了问题

void LCD_Init(void)
{
LCD_SendCommand(0x38);
LCD_SendCommand(0x38);
LCD_SendCommand(0x38);
LCD_SendCommand(0x06);
LCD_SendCommand(0x0c);
LCD_SendCommand(0x01);
LCD.BlinkEN = 0;
LCD.BlinkAdd = 0;
LCD.BlinkLen = 1;
LCD.BlinkCon = 0;
LCD_ScreenClear();
}

这是占了什么地址吗?怎么挡住了串口接收了
笨狗先飞 2018-11-22
  • 打赏
  • 举报
回复
引用 3 楼 sixto47 的回复:
[quote=引用 2 楼 bakw 的回复:] main函数初始化的时候把UsartInit(); 也加进去不就好了? 收到的信息反正都是在中断里处理的,收一字节存一字节,存到一个数组的缓冲区里。 设置一个全局标志位,数据接收的差不多了,就在中断里标记一下标志位, 主循环里判断一下,有接收标志位了,就去把缓冲区里的数据读过来,处理,该操作的操作,该发送的发送。
那我的TimerInit()里TMOD不会冲突吗,也写过,发现Interrupt 3 的失效了[/quote] 有些单片机串口是需要占用时钟的记得一般是T1吧,有些单片机有波特率发生器,避开串口需要占用的时钟 你的 UsartInit() 里用的 TMOD 是 0x20 ,占用第五位, TimerInit() 里是0x11,占用第零位和第四位, 你写的时候用 TMOD|=0x20 ,TMOD|=0x11这样来写,置位的时候就不会把之前的设定去掉了。 单片机里设置一个位一般都是 XXX|=xx来写1,需要写0用 XXX&=~xx来写某位的0
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 19 楼 bakw 的回复:
好象有独立的波特率发生器,那样,你时钟就独立可以用了。

是用的1T,我在排查有没有别的程序卡住了,已经用着独立的波特率发生器了
笨狗先飞 2018-11-22
  • 打赏
  • 举报
回复
好象有独立的波特率发生器,那样,你时钟就独立可以用了。
笨狗先飞 2018-11-22
  • 打赏
  • 举报
回复
串口配置大约是这个代码

#define IE_EA 0x80
#define IE_ES 0x10
#define AUXR_BRTR 0x10
#define AUXR_BRTx12 0x04
#define AUXR_S1BRS 0x01
#define PCON_SMOD 0x80
#define SCON_MODE1 0x40 //10位UART
#define SCON_REN 0x10
#define SCON_CLEAR 0xC0 //
#define XTAL 12000000
#define TCLK 0x01
#define Baud 9600

SCON &=~SCON_CLEAR;
SCON |= SCON_MODE1 | SCON_REN ;//串口工作方式设定
PCON |= PCON_SMOD; //波特率倍速模式
AUXR |= AUXR_BRTx12;
AUXR |= AUXR_S1BRS;
BRT = 0x100-XTAL/TCLK/16/Baud;//定时器初值设定(波特率设定)
AUXR |= AUXR_BRTR; //启动独立波特率发生器
IE |= IE_EA | IE_ES;


笨狗先飞 2018-11-22
  • 打赏
  • 举报
回复
你确定你的波特率对吗?
TL1=0
TH1=(0x100-XTAL/TCLK/16/Baud)

XTAL=12000000 晶振值
TCLK=计时器T数 不知道你是1T 2T 6T 还是 12T的
Baud = 波特率
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 4 楼 bakw 的回复:
[quote=引用 3 楼 sixto47 的回复:]
[quote=引用 2 楼 bakw 的回复:]
main函数初始化的时候把UsartInit(); 也加进去不就好了?
收到的信息反正都是在中断里处理的,收一字节存一字节,存到一个数组的缓冲区里。
设置一个全局标志位,数据接收的差不多了,就在中断里标记一下标志位,
主循环里判断一下,有接收标志位了,就去把缓冲区里的数据读过来,处理,该操作的操作,该发送的发送。


那我的TimerInit()里TMOD不会冲突吗,也写过,发现Interrupt 3 的失效了[/quote]
有些单片机串口是需要占用时钟的记得一般是T1吧,有些单片机有波特率发生器,避开串口需要占用的时钟

你的 UsartInit() 里用的 TMOD 是 0x20 ,占用第五位,
TimerInit() 里是0x11,占用第零位和第四位,
你写的时候用 TMOD|=0x20 ,TMOD|=0x11这样来写,置位的时候就不会把之前的设定去掉了。
单片机里设置一个位一般都是 XXX|=xx来写1,需要写0用 XXX&=~xx来写某位的0[/quote]

void TimerInit(void)
{
TMOD = 0x11;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
ET0 = 1;
TR0 = 1;
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
ET1 = 1;
TR1 = 1;
EA = 1;
}

void UsartInit(void)
{
SCON=0X50;
TMOD|=0X20;
PCON=0X80;
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
EA=1;
ES=1;
TR1=1;
}
是还少了什么吗?或者哪里出错了?串口接受不到而且影响到Interrupt3 干的事也没干成
sixto47 2018-11-22
  • 打赏
  • 举报
回复
引用 6 楼 sixto47 的回复:
[quote=引用 4 楼 bakw 的回复:]
[quote=引用 3 楼 sixto47 的回复:]
[quote=引用 2 楼 bakw 的回复:]
main函数初始化的时候把UsartInit(); 也加进去不就好了?
收到的信息反正都是在中断里处理的,收一字节存一字节,存到一个数组的缓冲区里。
设置一个全局标志位,数据接收的差不多了,就在中断里标记一下标志位,
主循环里判断一下,有接收标志位了,就去把缓冲区里的数据读过来,处理,该操作的操作,该发送的发送。


那我的TimerInit()里TMOD不会冲突吗,也写过,发现Interrupt 3 的失效了[/quote]
有些单片机串口是需要占用时钟的记得一般是T1吧,有些单片机有波特率发生器,避开串口需要占用的时钟

你的 UsartInit() 里用的 TMOD 是 0x20 ,占用第五位,
TimerInit() 里是0x11,占用第零位和第四位,
你写的时候用 TMOD|=0x20 ,TMOD|=0x11这样来写,置位的时候就不会把之前的设定去掉了。
单片机里设置一个位一般都是 XXX|=xx来写1,需要写0用 XXX&=~xx来写某位的0[/quote]
那TH1 TL1 只初始化一遍就可以了吧?[/quote]
您这个试了下,interrupt3 干的事好像被冲突掉了
在Usartinit()写没写TH1 TL1 都不行诶
sixto47 2018-11-21
  • 打赏
  • 举报
回复
引用 2 楼 bakw 的回复:
main函数初始化的时候把UsartInit(); 也加进去不就好了?
收到的信息反正都是在中断里处理的,收一字节存一字节,存到一个数组的缓冲区里。
设置一个全局标志位,数据接收的差不多了,就在中断里标记一下标志位,
主循环里判断一下,有接收标志位了,就去把缓冲区里的数据读过来,处理,该操作的操作,该发送的发送。


那我的TimerInit()里TMOD不会冲突吗,也写过,发现Interrupt 3 的失效了
加载更多回复(2)

27,521

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧