stc15w408as串口程序 P1口不能置零,设置为低电平后,P1口输出的还是高电平

查看: 18540|回复: 128
51单片机STC15W408AS做的无刷电调
看到很多人在用C8051做无感无刷电机的驱动,论坛里也好久没有做电调的动静了。今天我给大家来个国产51单片机STC15W408AS驱动无刷电机的驱动资料吧!
1.硬件设计
主控单片机使用STC15W408AS,这是STC在2014年新出的片子,2元一片,主频35M,无需外部晶振和复位电路,接好VCC和GND就可以工作。单片机自带硬件PWM模块、ADC模块和比较器模块,所以非常适合做无刷电机的驱动,半桥电路使用PMOS+NMOS的组合,PMOS为IRF9540,NMOS为IRF540.驱动芯片用TC4427A。
先在洞洞板上做实验吧。原理图如下所示,懒得用软件画了,还是手画来得快些。下面的图中,只画出了A相的桥,B相和C相的桥与A相一样。
BLDC原理图.jpg (39.61 KB, 下载次数: 12)
14:29 上传
按照原理图,焊接好元器件
BLDC电路板.jpg (87.97 KB, 下载次数: 5)
14:30 上传
连接好电机
STC51驱动BLDC1.jpg (41.75 KB, 下载次数: 4)
14:28 上传
2.软件设计
2.1PWM模块
void PWM_Init(void)
{
AUXR |= 0X80; //定时器0工作在1T模式
TMOD=0X02; // 定时器0工作于8位自动重载模式
TH0=0 // 产生23K的频率
TR0=1; // 打开定时器0
CMOD=0x04; //PCA的时钟选择“T0的溢出”
CL=0; // 计数器清0
CCAP0H=0; //PWM1占空比为0
CCAPM0=0x42;//开启PWM模式
CCAP1H=0; //PWM2占空比为0
CCAPM1=0x42; // 开启PWM模式
CCAP2H=0; // PWM3占空比为0
CCAPM2=0x42;//开启PWM模式
CR = 1;// 打开PCA
}复制代码
2.2ADC模块和比较器模块
比较器用来做反电动势的过零检测,选择P5.4引脚为比较器的负输入端,选择ADC通道为比较器的正输入端。
void CMP_Init(void) // 比较器初始化函数
{
CMPCR1=0X8C; // 打开比较器,把P5.4引脚设置为负输入端,ADC通道为正输入端
CMPCR2=50;// 延时消抖时间设置
}
void ADC_Init(void) // ADC模块初始化
{
P1ASF = 0X38; //开通P1.3 P1.4 P1.5端口的模拟输入端
}复制代码
2.3六步时序换相
BLDC的六步时序为AB AC BC BA CA CB,下面程序中,分别用0~5表示每一步。
void StepXL(void) // 换相序列函数
{
switch(Step)
{
&&case 0: // AB
&&CCAP0H=PWM_VCCAP1H=0;CCAP2H=0; // 打开A相的高端
&&PWM0_L=0;PWM2_L=0;PWM1_L=1; // 打开B相的低端
&&ADC_CONTR = 0XED; // 选择P1.5作为ADC输入 即c相电压
&&CMPCR1 |= 0x10; // 使能下降沿中断
&&
&&case 1: // AC
&&CCAP0H=PWM_VCCAP1H=0;CCAP2H=0; // 打开A相的高端
&&PWM0_L=0;PWM1_L=0;PWM2_L=1; // 打开C相的低端
&&ADC_CONTR = 0XEC; // 选择P1.4作为ADC输入 即B相电压
&&CMPCR1 |= 0x20; // 使能上升沿中断
&&
&&case 2: // BC
&&CCAP0H=0;CCAP2H=0;CCAP1H=PWM_V // 打开B相的高端
&&PWM0_L=0;PWM1_L=0;PWM2_L=1; // 打开C相的低端
&&ADC_CONTR = 0XEB; // 选择P1.3作为ADC输入 即a相电压
&&CMPCR1 |= 0x10; // 使能下降沿中断
&&
&&case 3: // BA
&&CCAP0H=0;CCAP2H=0;CCAP1H=PWM_V // 打开B相的高端
&&PWM1_L=0;PWM2_L=0;PWM0_L=1; // 打开A相的低端
&&ADC_CONTR = 0XED; // 选择P1.5作为ADC输入 即c相电压
&&CMPCR1 |= 0x20; // 使能上升沿中断
&&
&&case 4: // CA
&&CCAP0H=0;CCAP1H=0;CCAP2H=PWM_V // 打开C相的高端
&&PWM1_L=0;PWM2_L=0;PWM0_L=1; // 打开A相的低端
&&ADC_CONTR = 0XEC; // 选择P1.4作为ADC输入 即B相电压
&&CMPCR1 |= 0x10; // 使能下降沿中断
&&
&&case 5: // CB
&&CCAP0H=0;CCAP1H=0;CCAP2H=PWM_V// 打开C相的高端
&&PWM0_L=0;PWM2_L=0;PWM1_L=1; // 打开B相的低端
&&ADC_CONTR = 0XEB; // 选择P1.3作为ADC输入 即a相电压
&&CMPCR1 |= 0x20; // 使能上升沿中断
&&
&&default:
2.4电机启动函数
char QiDong(void)
{
unsigned int timer = 300,i;
DISABLE_CMP_INT;
PWM_Value = 26; // 占空比=26/256=10%
delay_ms(100);
{
&&for(i=0;i& i++)
&&{
& &delay_us(100); //
&&}
&&timer-= timer/15+1;
&&if(timer & 25) return(1);
&&if(Step&5)Step++;
&&else Step=0;
&&StepXL();
}
}复制代码
2.5闭环控制
电机启动以后,需要闭环控制电机的通电时序和速度。这个在比较器的中断函数里面实现。
void CMP_INT(void) interrupt 21 // 比较器中断函数
{
CMPCR1 &=~0X40; // 需软件清除中断标志位
if(Step&5)Step++;
else Step=0;
StepXL();
}复制代码
2.6通信控制接口
用电脑上的串口调试助手给单片机串口发送“启动”“加速”“减速”“停止”命令。这个功能放到主函数while循环中。
串口初始化函数:
void serial_open(void)
{
SCON = 0X50;//工作在串口模式
AUXR |= 0X04;//
TL2 = 0X71;// 9600 @35MHz
AUXR|=0X10;
}复制代码
主函数:
void main(void)
{
uchar rec=0; // 定义串口接收数据变量
PWM_Init(); // 初始化PWM
ADC_Init(); // 初始化ADC
CMP_Init(); // 初始化比较器
serial_open(); // 打开串口
{
&&if(RI) // 如果串口收到数据
&&{
& &rec=SBUF; // 把收到的数据给了rec
& &RI=0; // 串口接收标志清0
& &if(rec==0x22)// 加速命令
& &{
& & if(PWM_Value&250)
& & {
& &&&PWM_Value++; // 增加占空比
& & }
& &}
& &else if(rec==0x33)// 减速命令
& &{
& & if(PWM_Value&10)
& & {
& &&&PWM_Value--; // 减小占空比
& & }
& &}
& &else if(rec==0x11) // 启动命令
& &{
& & QiDong(); // 启动
& & ENABLE_CMP_INT; // 允许比较器中断
& & EA=1; // 打开全局中断
& &}
& &else if(rec==0x44) // 停止命令
& &{
& & CCAP0H=0;CCAP1H=0;CCAP2H=0;&&// 占空比都置0
& & EA=0; // 关闭全局中断
& & DISABLE_CMP_INT; // 关闭比较器中断
& &}
&&}
}
}复制代码
上面的软件和硬件,只是实现了简单的控制转动。
缺点:1.没有任何的保护程序,比如电流检测、堵转保护等。我在做实验的过程中,烧了2个PMOS、1个NMOS、3个TC4427A.
2.比较器过0直接换相,有些提前。电机转动噪音比较大。期待日后改进吧!或者哪位大侠伸手改进改进。
源程序工程文件:
(34.73 KB, 下载次数: 513)
14:35 上传
点击文件名下载附件
楼主威武,可以加个过温(但楼主这板子貌似不用)和过流保护
收下回去看下
51也可以搞BLDC啊?不错不错
学习了& && && && && && && && &
不错学习了!!& && &&&
支持楼主话说楼主在设计软件之前是否参考了什么资料
支持楼主话说楼主在设计软件之前是否参考了什么资料
参考了很多驱动无刷电机的资料!
支持楼主,学习了,顶一个
谢谢共享,mark
支持BLDC,谢谢!
支持楼主,建议还可以参考BLHELI开源程序。
支持楼主! 能否加入闭环控制
强大,支持楼主。
留个脚印,,回家慢慢看
挺好,谢谢。
本帖最后由 瑞生 于
11:05 编辑
发现了一个程序的大BUG,在换相函数里面,上升沿和下降沿的切换上,程序中只用了“或”,没有用“与”把之前的清掉,实际上变成双边沿中断了。为了运行速度,下面的程序直接赋值,不用“与”“或”赋值了。改了之后,电机的噪音小多了,尤其是在高速运转的时候。希望大师们继续改进!
void StepXL(void) // 换相序列函数
{
switch(Step)
&&{
& &case 0:&&// AB
& & & & CCAP0H=PWM_VCCAP1H=0;CCAP2H=0; // 打开A相的高端
& & & & PWM0_L=0;PWM2_L=0;PWM1_L=1; // 打开B相的低端
& & & & ADC_CONTR = 0XED; // 选择P1.5作为ADC输入 即c相电压
& & & & CMPCR1=0x9c; // 使能下降沿中断
& & & &
& &case 1:&&// AC
& & & & CCAP0H=PWM_VCCAP1H=0;CCAP2H=0; // 打开A相的高端
& & & & PWM0_L=0;PWM1_L=0;PWM2_L=1; // 打开C相的低端
& & & & ADC_CONTR = 0XEC; // 选择P1.4作为ADC输入 即B相电压
& & & & CMPCR1=0 // 使能上升沿中断
& && &
& &case 2:&&// BC
& & & & CCAP0H=0;CCAP2H=0;CCAP1H=PWM_V // 打开B相的高端
& & & & PWM0_L=0;PWM1_L=0;PWM2_L=1; // 打开C相的低端
& & & & ADC_CONTR = 0XEB; // 选择P1.3作为ADC输入 即a相电压
& & & & CMPCR1=0x9c; // 使能下降沿中断
& && &
& &case 3:&&// BA
& && && & & & CCAP0H=0;CCAP2H=0;CCAP1H=PWM_V // 打开B相的高端
& & & & PWM1_L=0;PWM2_L=0;PWM0_L=1; // 打开A相的低端
& & & & ADC_CONTR = 0XED; // 选择P1.5作为ADC输入 即c相电压
& & & & CMPCR1=0 & & & & // 使能上升沿中断& & & &
& && && & & &
& &case 4: // CA
& && && & & & CCAP0H=0;CCAP1H=0;CCAP2H=PWM_V // 打开C相的高端
& & & & PWM1_L=0;PWM2_L=0;PWM0_L=1; // 打开A相的低端
& & & & ADC_CONTR = 0XEC; // 选择P1.4作为ADC输入 即B相电压
& & & & CMPCR1=0 // 使能下降沿中断
& && && & & &
& &case 5: // CB
& &&&& & & &&&CCAP0H=0;CCAP1H=0;CCAP2H=PWM_V// 打开C相的高端
& &&&& & & &&&PWM0_L=0;PWM2_L=0;PWM1_L=1; // 打开B相的低端
& & & & ADC_CONTR = 0XEB; // 选择P1.3作为ADC输入 即a相电压
& & & & CMPCR1=0 // 使能上升沿中断
& && && & & &
& &default:
&&}& & & &
新的源代码工程:
(43.24 KB, 下载次数: 195)
11:05 上传
点击文件名下载附件
程序加入堵转保护了!实现方法,设置定时器T0产生50ms中断,在电机启动之后打开定时器T0,在换相中断比较器中,加入给T0初值的代码。这样,只要不堵转,就不会进去定时器T0中断函数;只要堵转,就会进入T0中断函数,关闭所有功率管,保护器件和电机不会烧坏!
上面的程序中,PWM的产生是用T0的溢出作为时钟源的,为了解放T0,我们设置PWM的时钟源为系统时钟,频率还设置为22K。
PWM初始化代码:
void PWM_Init(void)
{
& & & & PWM0_L=0;
& & & & PWM1_L=0;
& & & & PWM2_L=0;
& & & &
& & & & CMOD=0X0C; //选择系统时钟/6为时钟源,即频率=35M/6/256=22.8K
& & & & CL=0;& & & & & & & & & & & & // PCA计数器清零
& & & & CH=0;
& & & &
& & & & PCA_PWM0 = 0X00;
& & & & CCAP0H=0;& & // 初始化占空比为0% H的值装载到L中
& & & & CCAP0L=0;
& & & & CCAPM0=0x42;& & & & // 设置为PWM模式
& & & &
& & & & PCA_PWM1 = 0X00;
& & & & CCAP1H=0;& & // 初始化占空比为0%
& & & & CCAP1L=0;
& & & & CCAPM1=0x42;& & & & // 设置为PWM模式
& & & &
& & & & PCA_PWM2 = 0X00;
& & & & CCAP2H=0;& & // 初始化占空比为0%
& & & & CCAP2L=0;
& & & & CCAPM2=0x42;& & & & // 设置为PWM模式
& & & &
& & & & CR = 1;
}复制代码
T0初始化函数:
void T0_Iint(void)
{
& & & & TMOD=0X01; // T0工作于16位计数模式
& & & & TH0=0x00; //
& & & & TL0=0X00;
& & & & ET0=1;// 允许ET0中断
}复制代码
T0中断函数:
void T0_Int(void) interrupt 1
{
& & & & CCAP0H=0;CCAP1H=0;CCAP2H=0;&&// 占空比为0
& & & & PWM0_L=0;PWM1_L=0;PWM2_L=0;
& & & & TR0=0;
& & & & EA=0;
& & & & DISABLE_CMP_INT;
& & & & TH0=0x3C; // 计时10ms
& & & & TL0=0XAF;
& & & &
& & & & QiDong(); // 再次启动
& & & & ENABLE_CMP_INT; // 打开比较器中断
& & & & EA=1; // 打开总中断
& & & & TR0=1; // 打开定时器0
}复制代码
其它地方没有变
新的源代码工程:
(43.98 KB, 下载次数: 252)
09:42 上传
点击文件名下载附件
标记一下,回来电脑上仔细阅读
这个标记一下,谢谢分享。
赞一个!值得鼓励,希望您做的更好,加油!
程序加入堵转保护了!实现方法,设置定时器T0产生50ms中断,在电机启动之后打开定时器T0,在换相中断比较器 ...
楼主,你还在更新吗,能不能问你几个问题
楼主,你还在更新吗,能不能问你几个问题
问吧!不一定会
感谢分享,最近在驱动硬盘的主轴电机玩,
新出的15系列有这么便宜?15系列现在功能也算不错了
正好自己想学……赞一个!
15的要6块的吧
谢谢楼主,下载了
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
学习了,希望出过完整的图纸分享。
学习了,希望出过完整的图纸分享。
应广大网友要求,用PROTEL99SE画了个板子,已经交给嘉立创打样了,过几天回来给大家发板子!
做实验嘛,没有用小的封装,板子做的比较大!
PCB.png (17.23 KB, 下载次数: 4)
STC51单片机无刷电机BLDC电路板
12:44 上传
pdf原理图:
(89.35 KB, 下载次数: 388)
12:45 上传
点击文件名下载附件
stc51单片机BLDC电调电路板
完整的PROTEL99SE工程文件:
(170.33 KB, 下载次数: 234)
12:46 上传
点击文件名下载附件
stc51单片机BLDC电调电路板
这个不错,正需要。
向楼主学习& && && && && && &
楼主你这个为什么咯噔咯噔地响,像是柴油机?
51现在的片上外设其实也挺强大的。。。
能否做出高压的,比如直接220整流输出的310V驱动的
话说有没有这么样子的电机?
楼主威武& &
启动有点卡。整体还行吧
感谢lz,从lz的程序学到不少
楼主威武,超赞哦
感谢lz,从lz的程序学到不少
本帖最后由 CK345 于
08:04 编辑
楼主有pcb空板吗 搭车同学习
不错啊,值得学习
本帖最后由 瑞生 于
13:40 编辑
STC15W408AS驱动BLDC.jpg (1.17 MB, 下载次数: 3)
13:37 上传
今天好不容易有空,试了一下板子,噪音是由于换相不正时引起的,待后续大家共同改进,下面发出电路板的源程序KEIL工程文件。
(47.09 KB, 下载次数: 216)
13:36 上传
点击文件名下载附件
51也能做到这样的无刷,牛人,
感谢楼主!
早前拿到楼主代码,不错,可以启动,但是噪声大,后来我看了,是切换比较器的中断部分有点小问题,改了就比较好了。
比较器输入端我用了0.1uf电容,就更顺了,很稳定。
由于程序没有处理30度延时,所以0.1uf电容组成的RC刚好可以大约弥补高速时的30度延时。
控制改为了PPM脉冲,从P3.2输入,1.100ms~1.610ms为0~100%PWM。
另外,MOSFET建议换用SOP8封装的、低内阻的型号,否则大电流时,发热很大。
& & 换向有问题,速度上不去,电机没力。
把复杂的设计简单化就是高手。
这个相当不错啊
楼主是没有考虑PWM对比较器的影响吧……加0.1uf是可以滤除影响,但是对相位会有延时,且转速越高影响越大。到现在我还没找到去掉电容的方法,有些资料上说择多检测方式可行,也许可以试一下。有些大神早就把电容去掉了,就是不愿告知方法……
本帖最后由 瑞生 于
10:49 编辑
楼主是没有考虑PWM对比较器的影响吧……加0.1uf是可以滤除影响,但是对相位会有延时,且转速越高影响越大。 ...
我买了个好盈无刷电调,电路和我的一样简单,没有用电容,一样运行非常好,一点噪音也没有。
我通过示波器观察,它也是输出3路PWM,另3路控制通断,并不是人们说的6路PWM比较好。
今天有空,又修改了两个程序的BUG,噪音没有了(看下面的视频),但是还是没有加30度换相的代码,以后有空再加
BUG1:STC15W408AS的ADC转换完毕,要重新开启转换才可以
BUG2:STC15W408AS的比较器滤波时钟最大是0x3f,以前没有注意
视频地址:
最新的KEIL源代码:
(42.74 KB, 下载次数: 269)
11:45 上传
点击文件名下载附件
本帖最后由 118139 于
13:01 编辑
手头上也有几块用STC12C5204AD 外加比较器做的无刷电机驱动板,商品化的产品,
直流300V,电机可以大负载下频繁启停和运行,运行一般还可以。
a.jpg (203.11 KB, 下载次数: 2)
12:47 上传
背面用了集成了MOS管的,外加功率模块..
b.jpg (140.9 KB, 下载次数: 3)
12:47 上传
FSBB30CH60f
c.jpg (117.03 KB, 下载次数: 2)
12:47 上传
很不错,楼主高手!学习中。。。
请教下楼主,你做实验时,TC4427A烧毁的原因是什么?我现在也烧了好几个了,找不到原因
请教下楼主,你做实验时,TC4427A烧毁的原因是什么?我现在也烧了好几个了,找不到原因 ...
这个片子很容易烧,我也烧了好几个,不过现在不烧了
以前都是程序不完善,造成P管和N管都导通,造成电流过大的时候烧的。
这个片子很容易烧,我也烧了好几个,不过现在不烧了
以前都是程序不完善,造成P管和N管都导通,造成电流 ...
我的程序应该说不可能使上下臂同时导通的,但这片子还是很容易烧。有点摸不着北了。。对了,楼主你的电调发热严重吗?我的电调高速运转时3对MOS有一对很烫,而其他两对没什么温度。。这是MOS问题还是程序问题啊?
我的程序应该说不可能使上下臂同时导通的,但这片子还是很容易烧。有点摸不着北了。。对了,楼主你的电调 ...
我也遇到过这个有一对烫的问题,后来发现是TC4427的问题,你把TC4427两个互换,就能看出来
这个都可以,牛人呀!学习一下
我也遇到过这个有一对烫的问题,后来发现是TC4427的问题,你把TC4427两个互换,就能看出来 ...
嗯 好的 谢了
搭车问一下,单管驱动的直流电机,没有传感器能否探测到电机转速?
LS,比较困难。
您好,在论坛上看到你 《51单片机STC15W408AS做的无刷电调&&的这个帖子》,非常感兴趣;由于自己也正在学习这个,非常渴望能够自己测试下,所以想问下你的电路板还有么,能否送我几片做测试学习,卖给我也可以。期待你的回复。
学习学习!
这个片子 有几个定时器?
MARK& && &
这个片子 有几个定时器?
两个定时器,3路PCA用做 PWM,还有ADC
您好,在论坛上看到你 《51单片机STC15W408AS做的无刷电调&&的这个帖子》,非常感兴趣;由于自己也正在学习 ...
不好意思,现在没有了
这个不错,可以有
两个定时器,3路PCA用做 PWM,还有ADC
还有定时器就能做延时三十度吧。
收藏学习,楼主碉堡了
mark,努力学习
楼主能否留个邮箱交流学习学习
上次看了吗没有学会,又来了
学习了,不错!
不错,做个记号
楼主你的程序怎么没有对续流状态过零点误检测的判断?以及PWM开关干扰下也会造成过零点误检测,这些你都没有遇到过吗?
记号,学习了
不错,先收下了。回再看。
学习了,正好需要这个东西
赞一个!值得鼓励,希望您做的更好,加油!
应广大网友要求,用PROTEL99SE画了个板子,已经交给嘉立创打样了,过几天回来给大家发板子!
做实验嘛,没 ...
楼主请问一下,这个检测换向的问题,因为PWM是由硬件产生的,那么是不是每当这个PWM从高到低或者从低到高的时候,都是需要换向一次呢?那如果这个PWM的频率达到100K了,占空比为50%时,那是不是相当于约5us就要进行换向一次呢?
谢谢指导一下
本帖最后由 知识阅览者 于
11:46 编辑
哦,这个文件好像早就看到过了!而且在STC官网也有内容的!!!
更改一下,我确实也是在瑞生电子论坛看到的!!!没有看到楼主就是瑞生!!!!
知识阅览者 发表于
哦,这个文件好像早就看到过了!而且在STC官网也有内容的!!!
请问一下,我在上一楼说的对吗?
请问一下,我在上一楼说的对吗?
不好意思,我只是看到这个知识点,没有去做实验!!!
谢谢 我也准备做一个
牛人啊, 新人慢慢学~
楼主威武。
楼主,你连消磁事件都没有进行滤波还能转起来让我很诧异,而且你没有加rc滤波,噪声应该很多的,还能正常换相,是因为stc15的比较器输入内部带rc滤波吗?
我看了一下st15资料,原来内部有比较延时时钟设置,楼主你的效率怎么样,我的无负载还行,有负载就挂了
不是STC15W404AS吗?
楼主毕设中参考了你的无刷电机拓补电路,谢谢楼主
阿莫电子论坛, 原"中国电子开发网"查看: 4173|回复: 8
求助STC15W408AS串口不能收发数据的问题
看到这款单片机是宽电压的,就买了几个回来用,结果一测试串口,发现死活不能通讯(用示波器看,直接不能输出数据),同样的程序放在之前老款型号(STC12****)的芯片里正常,就是这款芯片不行,发现这就款芯片的数据手册写的非常乱,把几个不同的芯片的数据手册全部写到一起,不知道老妖这是在干嘛,刚刚论坛看了一下,吃亏的还不止我一个,有没有兄弟调通过,指教一下,谢谢。
把程序贴出来看看?
#include&reg51.h&
#include&string.h&
#define Buf_Max 254 & & & & & & & & //缓存长度200
#define Delay_Time 3000& &&&//延时长度
unsigned char i=0;& && && && && && && &//定义缓存指针
unsigned char Rec_Buf[Buf_Max];& & & && && &&&//定义缓存数组
void Serial_Init(void);& && &&&//声明串口初始化函数
void Send_ASCII(unsigned char *b);& &&&//声明发送字符(ASCII码)函数
void Delay(unsigned int Time);& && && &//声明延时函数
void CLR_Buf(void);& && && && &//声明清除缓存内容
bit Hand(unsigned char *e);& && && && &//声明判断缓存中是否含有指定的字符串函数
void main(void)
& & & & Serial_Init();& &//初始化串口
& & & & CLR_Buf();& && &&&
& & & & Delay(300);
& & & & while(1)
& & & & & & & & while(!Hand(&OK&))& && & //判断是否握手成功,如果不成功,再发一次握手指令
& & & & & & & & {
& & & & & & & & & & & & Send_ASCII(&AT&);& & & &&&//发送AT联机指令
& & & & & & & & & & & & Delay(600);
& & & & & & & & }& & & &
& & & & }& & & &
void Serial_Init(void)//串口初始化函数
& & & & SCON = 0x50;//串口:方式1,允许发送和接收
& & & & TMOD = 0x20;//定时器1:模式2,8位自动重装模式,用于产生波特率& &
& & & & TH1 = 0 //11.0592MHZ晶振,波特率为9600
& & & & TL1 = 0& &
& & & & TR1 = 1;& & //开启定时器1& &
& & & & ES = 1;& &&&//开启串口中断
& & & & EA = 1;& &&&//开启全局中断
void Send_ASCII(unsigned char *b)& && && &
& & ES = 0;& && && && && && & //关串口中断
& & for (b; *b!='\0';b++)
& & & & & & {
& && &&&& & & & SBUF = *b;
& && &&&& & & & while(TI!=1);& &&&//等待发送完成
& & & & & & & & & & & & TI = 0;& && && &&&//清除发送中断标志位
& & & & & & & & }& & & && &
& & & & ES = 1;& && && && && && & //开串口中断
void CLR_Buf(void)& & & && &//清除缓存内容
& & for(k=0;k&Buf_Mk++)& & //将缓存内容清零
& & & && &&&{
& & & & & & & & & & & & Rec_Buf[k] = 0;
& & & & & & & & }
& & i = 0;& && && && && && &&&//接收字符串的起始存储位置
void Delay(unsigned int time)&&//延迟服务函数
for(;time&0;time--)
&&& & & & & & & & j = 1500;
&&& & & & & & & & while(j--);
void Send_Hex(unsigned char b)& && && &
& & ES = 0;& && && && && &//关串口中断
& & SBUF =
& & while(TI!=1);& && && &//等待发送完成
& & TI = 0;& && && && && &//清除发送中断标志位
& & & & ES = 1;& && && && && &//开串口中断
bit Hand(unsigned char *e)& & & & //判断缓存中是否有指定字符
& & if(strstr(Rec_Buf,e)!=NULL)
& & & && &&&return 1;
& & & & else
& & & & & & & & return 0;
void Serial_Int() interrupt 4 & & & & //串口中断服务函数
& & & & ES = 0;& & & &&&//关串口中断,防止中断嵌套
& & & & if(TI)& & & &&&//如果是发送中断,则不做任何处理
& & & & & & & & {
& & & & & & & & & & & & TI = 0;&&//清除发送中断标志位
& & & & & & & & }
& & & & if(RI)& & & &&&//如果是接送中断,则进行处理
& & & & & & & & {
& & & & & & & & & & & & RI = 0; //清除接收中断标志位
& & & & & & & & & & & & Rec_Buf[i] = SBUF; //将接收到的字符串存到缓存中
& & & & & & & & & & & & i++;& && && && && &//缓存指针向后移动
& & & & & & & & & & & & if(i&254)& && && & //如果缓存满,将缓存指针指向缓存的首地址
& & & & & & & & & & & & & & & & {
& & & & & & & & & & & & & & & & & & & & i = 0;
& & & & & & & & & & & & & & & & }
& & & & & & & & }
& & & & ES = 1;& & & &&&//开启串口中断
楼主你发送程序,明明是查询方式的发送,没在中断里发送,还开什么发送中断啊,中断函数改成这样就行了,中断只开接收中断
void Serial_Int() interrupt 4& && && &//串口中断服务函数
& && &RI = 0; //清除接收中断标志位
& && & Rec_Buf[i] = SBUF; //将接收到的字符串存到缓存中
& && &&&i++;& && && && && &//缓存指针向后移动
& && &&&if(i&254)& && && & //如果缓存满,将缓存指针指向缓存的首地址
& && && &&&{
& && && && && &i = 0;
& && && & }
本帖最后由 瑞生 于
09:06 编辑
这个单片机没有定时器1,只有定时器0和2,所以你用定时器1怎么弄也出不来的。给你个定时器2设置的串口代码吧:
void serial_open(void)
{
SCON = 0X50;//工作在串口模式
AUXR |= 0X04;//
TL2 = 0X71;// 9600 @35MHz主频
TH2 = 0X
AUXR|=0X10;
}复制代码
我拿这个单片机做了两个应用了
第7章 定时器/计数器
STC15F2K60S2系列单片机内部设置了3定时器:3个16位定时器/计数器T0和T1以及定时
器T2。3个16位定时器T0、T1和T2都具有计数方式和定时方式两种工作方式。对定时器/计数
器T0和T1,在特殊功能寄存器TMOD中都有一控制位— C/T来选择T0或T1为定时器还是计数器。
而对定时器/计数器T2,在特殊功能寄存器AUXR中都有一控制位— T2_C/T来选择T2为定时器
还是计数器。定时器/计数器的核心部件是一个加法计数器,其本质是对脉冲进行计数。只是
计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个
时钟或者每1个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部 引脚(T0为
P3.4,T1为P3.5,T2为P3.1),则为计数方式,每来一个脉冲加1。
当定时器/计数器T0、T1及T2工作在定时模式时,特殊功能寄存器AUXR中的T0x12、T1x12
和T2x12分别决定是系统时钟/12还是系统时钟/1(不分频)后让T0、T1和T2进行计数。当定时器
/计数器工作在计数模式时,对外部脉冲计数不分频。
定时器/计数器0有4种工作模式:模式0(16位自动重装载模式),模式1(16位不可重装载模
式),模式2(8位自动重装模式),模式3(两个8位定时器/计数器)。定时器/计数器1除模式3外 ,
其他工作模式与定时器/计数器0相同,T1在模式3时无效,停止计数。定时器T2的工作模式固
定为16位自动重装载模式。T2可以 当定时器使用,也可以 当串口的波特率发生器和可编程时钟
这是我下载的STC15W408AS手册,手册上是有T1的呀!
谢谢5楼的提醒,找了一段代码,我的可以收到消息了
(use%20Timer%202%20as%20a%20baud%20rate%20generator).c
玩了一下stc,看老姚的手册,死的心都有了
stc不是都通用的
阿莫电子论坛, 原"中国电子开发网"

我要回帖

更多关于 stc15w408as内置的pwm 的文章

 

随机推荐