6938|10

68

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

1.由上位机发送1给单片机时,蜂鸣器以400ms频率发声,发2时以200ms频率发声,发3时以100ms频率发声,发4时关闲蜂鸣器。 [复制链接]

程序 如下:
#include
#define uchar unsigned char
#define uint unsigned int

uint fre,a;
sbit b=P2^3;

void init();

void main()
{
  init();
  
  while(1){
  if(RI==1){
     RI=0;
          ES=0;          
          switch(a){
                  case 1:fre=2500;
                       break;
                  case 2:fre=5000;
                       break;
                  case 3:fre=10000;
                       break;
                  case 4:fre=50000;
                  break;
          }   
    ES=1;
         if(a==1||a==2||a==3){
           TH0=(65536-fre)/256;
           TL0=(65536-fre)%256;
                ET0=1;  
           TR0=1;
          }else{
             TR0=0;                 
          }
               
   }
  }
}



void init(){
   a=0;
        fre=0;
       

        TMOD=0x21; //确定T1的工作方式 定时器
        TH1=0xfd;  //装载TH1,TL1
        TL1=0xfd;
        TR1=1;     //启动T1
       
        SM0=0;      //确定串行口控制 ,TI,RI 也需要使用软件设置
        SM1=1;
        REN=1;
        //中断设置
        EA=1;  //cpu中断允许位
        ES=1;  //串行中断允许位
        IP=0x10;
   
        //使用定时器0控制频率
        //TMOD=0x01;  

                 
}

void timer() interrupt 1
{
   TH0=(65536-fre)/256;
        TL0=(65536-fre)%256;
        b=~b;
}

void ser() interrupt 4
{
        RI=0;
        a=SBUF;
}
麻烦帮我看看有什么问题

最新回复

这个也能实现,可参考一下 #include #include unsigned flag,temp; sbit BEEP=P3^4; void delay(unsigned int timer) {         unsigned int i,j;         for(i=timer;i>0;i--)                 for(j=120;j>0;j--); } void beep(unsigned int freq) { //        unsigned int i;         BEEP=0;         delay(freq);         BEEP=1;         delay(freq); } void main(void)   {         unsigned char ldat;         EA=1;                                        //开启总中断                TMOD=0X20;                                //设置定时器1为模式2,做为波特率发生器         TL1=0xF3;                                //9600波特率的初值,板子使用12M晶振,初值=256-12000000/32/12/2400         TH1=0xF3;                                //         TR1=1;                                        //启动波特率发生         SCON=0x50;                                //串口方式2         ES=1;         while(1)         {                 if(flag==1)                 {                         ES=0;                         flag=0;                         SBUF=temp;                         while(!TI);                         TI=0;                         ES=1;                 }           /*        if(RI)                 {                                P0=SBUF;                //查询是否有数据接收                         ldat=SBUF;                //数据暂存于变量中                         RI=0;                        //重新清0等待接收                         SBUF=ldat;                //将接收到的数据发送出去                         while(!TI);                //等待发送完成                         TI=0;                 }*/         }        } void ser() interrupt 4 {         RI=0; //        P0=SBUF;         temp=SBUF;         switch(temp)         {                 case 1:beep(400);break;                 case 2:beep(200);break;                 case 3:beep(100);break;                 case 4:BEEP=1;break;                 default :break;         }         flag=1; }  详情 回复 发表于 2010-4-29 19:34
点赞 关注

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
你这程序是编译有错还是运行有错?65536改成65535吧。不然32位除法运算对单片机来说太慢了。
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
楼主 不先说什么问题,那怎么帮你看啊
 
 
 

回复

55

帖子

0

TA的资源

一粒金砂(初级)

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

我使用串口调试助手 发1,2,3不同数字时,频率会变化,但是发4时优势可以关闭蜂鸣器,有时不能关闭。
一直在响

不解
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

5
 
你停止定时器的时候,控制蜂鸣器的那个引脚的电平不确定。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

6
 
  1. else
  2. {
  3. TR0 = 0;
  4. b = 0;//b = 1;
  5. }
复制代码


怎么感觉怪怪的
中断里RI = 0了
主程序又判断if(RI == 1)
...
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

7
 
有没有好心人帮我看看,我分不够,不能发帖
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define COUNT 7
sbit beep=P2^3;
sbit dula=P2^6;
sbit wela=P2^7;
sbit adwr=P3^6;            //定义A/D的WR端口
sbit adrd=P3^7;                   //定义A/D的RD端口     
unsigned char buffer[COUNT];              
unsigned char flag,a,point,RECEIVR_buffer,adval;       
void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)
            for(j=110;j>0;j--);
}
void UART_init()
{
        TMOD=0x20;//设置定时器1为工作方式2
        TH1=0xfd;
        TL1=0xfd;
        TR1=1;
        ET1=0;
        REN=1;
        SM0=0;
        SM1=1;
        EA=1;
        ES=1;
        PS=1;
        point=0;       
}
void AD()
{
        wela=1;
        P0=0x7f;
        wela=0;
        adwr=1;
        _nop_();
        adwr=0;
        _nop_();
        adwr=1;
        _nop_();
        adrd=1;                   //选通ADCS
        _nop_();
        adrd=0;                   //A/D读使能
        _nop_();
        adval=P1;                 //A/D数据读取赋给P1口
        adrd=1;
}
void sendbyte()
{
        ES=0;
        SBUF=buffer[0];       
        while(!TI);       
        TI=0;
        SBUF=buffer[1];
        while(!TI);       
        TI=0;
        SBUF='a';
        while(!TI);       
        TI=0;
        SBUF=adval;       
        while(!TI);       
        TI=0;
        SBUF=adval;
        while(!TI);       
        TI=0;
        SBUF=adval;
        while(!TI);       
        TI=0;
        SBUF=buffer[6];
        while(!TI);       
        TI=0;
        delayms(700);                          
        ES=1;
        point=0;
}
void main()
{          
         UART_init();
         while(1)
         {
         if(flag==1)
                                {  RI=0;
                                   if(buffer[3]=='A')
                                   {P1=0xaa;}
                                   else if(buffer[3]=='B')
                                   {P1=0xbb;}                                 
                                }
         }
}

com_interrupt(void) interrupt 4
{
        unsigned char RECEIVR_buffer;
        if(RI==1)         
        {
                RI=0;      
                RECEIVR_buffer=SBUF;
                if(point==0)                     //如果还没有接收到起始位
                {   
                        if(RECEIVR_buffer=='&')      //判断是否为起始标志位‘&’
                        {
                                buffer[0]=RECEIVR_buffer;
                                point++;
                        }
                        else        point=0;
                }
                else if(point>0&&point<7)     //判断是否接收够10位数据
                {
                                        buffer[point]=RECEIVR_buffer;
                                        if(point==6)
                                        {
                                                beep=0;
                                delayms(50);
                                beep=1;
                                                flag=1;
                                        }
                                        point++;
                                }                     //若不够,把收到的数据放入接收缓存区
                else if(point>7){point=0;}                 //缓存区已满,point清零
           }
        if(TI==1)               
        {
     TI=0;
        }

}               
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

8
 
前面一段程序有点问题,下面是对的。。那个我的问题是在pc发送的命令相互切换时,C命令(也就是循环发送命令)无法切换到其他命令,有没有人帮我想想办法??
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define COUNT 7
sbit beep=P2^3;
sbit dula=P2^6;
sbit wela=P2^7;
sbit adwr=P3^6;            //定义A/D的WR端口
sbit adrd=P3^7;                   //定义A/D的RD端口     
unsigned char buffer[COUNT];              
unsigned char flag,a,point,RECEIVR_buffer,adval;       
void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)
            for(j=110;j>0;j--);
}
void UART_init()
{
        TMOD=0x20;//设置定时器1为工作方式2
        TH1=0xfd;
        TL1=0xfd;
        TR1=1;
        ET1=0;
        REN=1;
        SM0=0;
        SM1=1;
        EA=1;
        ES=1;
        PS=1;
        point=0;       
}
void AD()
{
        wela=1;
        P0=0x7f;
        wela=0;
        adwr=1;
        _nop_();
        adwr=0;
        _nop_();
        adwr=1;
        _nop_();
        adrd=1;                   //选通ADCS
        _nop_();
        adrd=0;                   //A/D读使能
        _nop_();
        adval=P1;                 //A/D数据读取赋给P1口
        adrd=1;
}
void sendbyte()
{
        ES=0;
        SBUF=buffer[0];       
        while(!TI);       
        TI=0;
        SBUF=buffer[1];
        while(!TI);       
        TI=0;
        SBUF='a';
        while(!TI);       
        TI=0;
        SBUF=adval;       
        while(!TI);       
        TI=0;
        SBUF=adval;
        while(!TI);       
        TI=0;
        SBUF=adval;
        while(!TI);       
        TI=0;
        SBUF=buffer[6];
        while(!TI);       
        TI=0;
        delayms(500);                          
        ES=1;
        point=0;
}
void main()
{          
         UART_init();
         while(1)
         {
         if(flag==1)
                                {
                                switch(buffer[3])
{
        case 'A':{       
                                P1=0;
                   };break;            //启动传感器
        case 'B':{
                    AD();
                                beep=0;
                                delayms(50);
                                beep=1;
                                delayms(1000);
                           };break;            //开始AD转换
        case 'C':{
                    AD();
                                beep=0;
//                                delayms(50);
                                beep=1;
                                sendbyte();
                                };break;            //开始传送数据
        case 'D':{
                                AD();
                                beep=0;
                                delayms(50);
                                beep=1;
                                delayms(1000);
                                };break;            //停止传送数据
        case 'E':{P1=0;};break;            //停止AD转换
        case 'F':{P1=0xff;};break;            //关闭传感器
}
                                }
         }
}

com_interrupt(void) interrupt 4
{
        unsigned char RECEIVR_buffer;
        if(RI==1)         
        {
                RI=0;      
                RECEIVR_buffer=SBUF;
                if(point==0)                     //如果还没有接收到起始位
                {   
                        if(RECEIVR_buffer=='&')      //判断是否为起始标志位‘&’
                        {
                                buffer[0]=RECEIVR_buffer;
                                point++;
                        }
                        else        point=0;
                }
                else if(point>0&&point<7)     //判断是否接收够10位数据
                {
                                        buffer[point]=RECEIVR_buffer;
                                        point++;
                                        if(point==7)
                                        {
                                                beep=0;
                                delayms(50);
                                beep=1;
                                                flag=1;                               
                                                point=0;
                                        }                                       
                                }                     //若不够,把收到的数据放入接收缓存区
           }
        if(TI==1)               
        {
     TI=0;
        }

}
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

9
 
问题应该是在发送数据时ES反复置零置一产生的,有没有什么方法解决这问题?谢谢大家了~
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

10
 
8楼,,,看你程序的意思是想通过选择ABCD...来控制AD转换,并通过串行通讯传送到上位机。。单片机这里是发送机,是主动地,需要引起中断的是接收机,而你这里的接收机是上位机pc,你是通过选择C主动调用来串行传输数据的,,,那么你那个所谓的串行中断完全是不必要的啊 ,你写那个中断干吗呢。。。单单用一个sendbyte()函数就可以把你AD转换的数值传送到上位机了。。。你加了个中断不是画蛇添足么,,,这样你那一大堆的EA,ES什么的根本不需要反复置位 复位了。。。。。
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

11
 
这个也能实现,可参考一下
#include
#include
unsigned flag,temp;
sbit BEEP=P3^4;
void delay(unsigned int timer)
{
        unsigned int i,j;
        for(i=timer;i>0;i--)
                for(j=120;j>0;j--);
}

void beep(unsigned int freq)
{
//        unsigned int i;
        BEEP=0;
        delay(freq);
        BEEP=1;
        delay(freq);
}
void main(void)  
{
        unsigned char ldat;
        EA=1;                                        //开启总中断       
        TMOD=0X20;                                //设置定时器1为模式2,做为波特率发生器
        TL1=0xF3;                                //9600波特率的初值,板子使用12M晶振,初值=256-12000000/32/12/2400
        TH1=0xF3;                                //
        TR1=1;                                        //启动波特率发生
        SCON=0x50;                                //串口方式2
        ES=1;
        while(1)
        {
                if(flag==1)
                {
                        ES=0;
                        flag=0;
                        SBUF=temp;
                        while(!TI);
                        TI=0;
                        ES=1;
                }
          /*        if(RI)
                {       
                        P0=SBUF;                //查询是否有数据接收
                        ldat=SBUF;                //数据暂存于变量中
                        RI=0;                        //重新清0等待接收
                        SBUF=ldat;                //将接收到的数据发送出去
                        while(!TI);                //等待发送完成
                        TI=0;
                }*/
        }       
}

void ser() interrupt 4
{
        RI=0;
//        P0=SBUF;
        temp=SBUF;
        switch(temp)
        {
                case 1:beep(400);break;
                case 2:beep(200);break;
                case 3:beep(100);break;
                case 4:BEEP=1;break;
                default :break;
        }
        flag=1;
}
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表