微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 串行口通信单片机根据上位机发送的数字控制蜂鸣器发声

串行口通信单片机根据上位机发送的数字控制蜂鸣器发声

时间:11-22 来源:互联网 点击:
一. 程序功能

上位机发送1给单片机,蜂鸣器以400ms频率发声,发送2时以200ms频率发声,发送3时以100ms频率发声,发送4时关闭蜂鸣器.

二. 程序源码

#include

//声明程序需要的全局变量

unsigned char flag, a, num, benum;

//声明单片机的蜂鸣器

sbit beep = P2 ^ 3;

//声明初始化函数

void init();

//主函数

void main()

{

//初始化

init();

while (1)

{

//检测是否发生串口中断

if (flag == 1)

{

//手动将flag置0,方便下次检测

flag = 0;

//关闭中断???为什么需要关闭总中断而不仅仅是串口中断

EA = 0;

//开启计数器0

TR0 = 1;

//根据串口接收的数据设置蜂鸣器的频率基数

switch(a)

{

case 1:

benum = 4;

break;

case 2:

benum = 2;

break;

case 3:

benum = 1;

break;

case 4:

TR0 = 0;

beep = 1;

}

//开启总中断

EA = 1;

}

}

}

void init()

{

//设置定时器1为工作方式2, 定时器0为工作方式1

TMOD = 0x21;

//波特率 = (2的SMOD次方/32) * (T1溢出率) //T1溢出率 = [256 - X]*12/晶振频率

//根据SMOD的0,1取值得到的X分别为TH1,TL1

//波特率选取9600,晶振频率为11.0592

TH1 = 0xfd;

TL1 = 0xfd;

//以50s作为计数器0的基数

TH0 = (65536 - 50000) / 256;

TL0 = (65536 - 50000) % 256;

//ET1 = 1; 这里不需要开启定时器1中断,因为定时器1工作在方式2,为8位自动重装方式,进入中断也无事可做

//启动T1定时器

TR1 = 1;

//开启T0定时器

ET0 = 1;

//TR0 = 1; TR0的初始化放在主函数的while中,从而启动T0定时器,使蜂鸣器按频率发声

//设定串口工作方式

//10位异步收发(8位数据), 波特率可变(由定时器溢出率控制)

SM0 = 0;

SM1 = 1;

//容许串口中断

REN = 1;

//开启总中断

EA = 1;

//开启串口中断

ES = 1;

}

void ser() interrupt 4

{

//RI为接收中断标志位, 在方式0时, 当串行接收第8位数据结束时, 或在其他方式, 串行接收停止位的

//中间时, 由内部硬件使RI置1, 向CPU发出中断申请, 也必须在中断服务程序中, 用软件将其清0,取消

//此中断申请, 以方便下一次中断申请检测, 即这样才能产生下一次中断.

//这里RI清0, 因为程序既然产生了串口中断, 肯定是收到或发送了数据, 在开始时没有发送任何数据

//那必然是收到了数据, 此时RI会被硬件置1, 所以进入串口中断服务程序后必须由软件清0, 这样才能

//产生下一次中断.

RI = 0;

//将SBUF中的数据读走给a, 这是此中断服务程序最重要的目的

a = SBUF;

//将串口中断标志位置1,方便主程序检测

flag = 1;

}

void T0_timer() interrupt 1

{

TH0 = (65536 - 50000) / 256;

TL0 = (65536 - 50000) % 256;

num++;

if (num == benum)

{

num = 0;

beep = ~beep;

}

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top