数码之家

 找回密码
 立即注册
搜索
查看: 1216|回复: 7

[C51] 小白自学C51单片机编程,输出PWM信号增加按键和报警

[复制链接]
发表于 2023-12-26 17:08:58 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
谢谢大家支持,因为是小白自学,只能从最简单的慢慢学,让大家见笑了,
今天在昨天基础上增加了按键,用于改变占空比,到达上限时报一下警,
以下是硬件部分,电路和脚位

fa606dce14fbdf5e9120e769281d53b.png

a399392adfb84998e92f3c93dff3450.png

656fa486d913891c0d8197f46fbce96.png
81b68e48d89ea1670df44f1465772c8.png
以下是实测波形,

7f2a02999a512480d72b32a5bd4ecf7.jpg

72c3ecfc6ab90a577d73fa456973a24.jpg

fc0c69e0d9c733119b0a5b3a142a2a3.jpg

以下是代码,和我的一些理解,有不对的地方请指教,谢谢

//程序功能:P1.0口输出PWM信号
//增加按键加减占空比,key3增加key4减少
//当增加到95时声音报警,当减少到5时报警,

#include <reg52.h>        //头文件
typedef unsigned char uchar;    //类型定义,相当于缩写的意思吧
typedef unsigned int uint;      //类型定义

sbit PWM=P1^0;    //P1.0口输出PWM信号
uchar time;     //定义周期时间
uchar duty=50;    //定义占空比,并给初值   
sbit key3=P3^6;         //定义一个按键加
sbit key4=P3^7;         //定义一个按键减
sbit beep=P0^7;         //定义报警位
uint xms;    //延时时间

void time0init();    //声明子函数定时器初始化
void delay(xms);    //声明子函数延时
void key_scan();    //声明子函数按键

void main ()      //主函数
{
    time0init();    //调用初始化子函数
    while(1)
    {
         key_scan();    //调用按键子函数
    }
}

void delay (xms)    //延时子函数
{
     uchar i;    //定义一个变量,函数内的变量只对当前函数有效
    while(xms--)    //给定值自减,
    {
         for(i=0;i<113;i++);    //每一个算是单位是不是113个机器周期?
    }
}

void key_scan()       //检测按键子函数
{
     if(key3==0)       //如果key3被按下,
    {
         delay(5);    //抖消
        if(key3==0)         //再次确认
        {
             duty+=5;    //占空比加5
            if(duty>=95)   //最大到95
            {
                 duty=95;
                beep=!beep;    //报警响
            }
            while(key3==0);     //按键释放
        }
    }
    if(key4==0)       // key4原理一样
    {
         delay(5);    //
        if(key4==0)
        {
             duty-=5;    //
            if(duty<=5)   //
            {
                 duty=5;
                beep=!beep;    //
            }
            while(key4==0);
        }
    }
}

void time0init()     //定时器初始化函数
{
    EA=1;        //开总中断
    ET0=1;        //开定时器0        
    TR0=1;        //定时器0开始
    TMOD=0X01;    // 定时器模式1
    TH0=(65536-10)/256;      //10ms初值高8位
    TL0=(65536-10)%256;      //10ms初值低8位
}

void time0 ()interrupt 1    //定时器中断函数
{   
    TR0=0;                 //
    TH0=(65536-10)/256;
    TL0=(65536-10)%256;
    TR0=1;                 //
    time++;    //
     if(time>=100)      //如果定时满了100次
        time=0;        //定时清零
    if(time<=duty)    //如果小于10,相当于只有10%时间是高电平,
        PWM=1;          //输出高电平
    else
         PWM=0;          //其它时间输出低电平
}     



打赏

参与人数 1家元 +30 收起 理由
家睦 + 30

查看全部打赏

 楼主| 发表于 2023-12-26 17:09:36 | 显示全部楼层
上个视频
a2a65a08bb8e6e54b6374f515d4b5df8.mp4 (4.16 MB, 下载次数: 0)

回复 支持 反对

使用道具 举报

发表于 2023-12-26 17:28:42 | 显示全部楼层
真的有反应,好神奇啊
回复 支持 反对

使用道具 举报

发表于 2023-12-26 17:54:34 | 显示全部楼层
现在小白配置也这么高吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-26 20:15:49 | 显示全部楼层
ling11052001 发表于 2023-12-26 17:54
现在小白配置也这么高吗

哪里高了,最古老的单片机,最便宜的开发板,10年前的小本本,上网本太小,打字时经常会误碰触摸板
回复 支持 反对

使用道具 举报

发表于 2023-12-26 21:38:17 | 显示全部楼层
好像前几天还在问定时器问题,今天就玩到这个水平了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-28 09:21:59 | 显示全部楼层
试验发现定时器初值太大实际频率误差很大,原因各们大神都分析了,现在我想把初值设为100uS定时次数改成10次,
新的问题是占空比不知道怎样设置了,之前是100次,占空比在5~95之间,如果改成了10次,占空比就是0.5-9.5了,这个小数程序要怎样处理?
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-29 07:08 , Processed in 0.140400 second(s), 16 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表