找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2196|回复: 3
收起左侧

单片机PWM呼吸灯程序问题

[复制链接]
ID:880867 发表于 2021-2-18 16:21 | 显示全部楼层 |阅读模式
heighHR0 = (u8)(heigh >> 8);//高电平装入初值的高字节
heighLR0 = (u8)heigh; //高电平装入初值的低字节
想问这个是怎么装入的过程?heigh是16位的吗?高电平装入初值的低字节这个过程没看懂?求大佬举例详解
单片机源程序如下:

  1. /*
  2. 实验接线:
  3.         AD/DAC模块-->单片机管脚
  4.         J50-->P21
  5. 实验现象:
  6.         AD/DAC模块上的DA1指示灯呈呼吸灯效果
  7. */


  8. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器


  9. //对数据类型进行声明定义
  10. typedef unsigned char u8;
  11. typedef unsigned int u16;
  12. typedef unsigned long u32;

  13. //--定义使用的IO口--//
  14. sbit PWMOUTLED=P2^1;

  15. //#define SYSCLOCK        11059200                //晶振频率是11.0592MHZ
  16. #define SYSCLOCK        12000000                //晶振频率是12MHZ

  17. u8 heighHR0, heighLR0;//PWM一个周期中高电平高字节和低字节重载值
  18. u8 lowHR0, lowLR0;//PWM一个机器周期中低电平时高字节和低字节重载值



  19. /*使用T0配置PWM高低电平的频率*/
  20. void PWM_Config(u16 fr, u8 dc)  //fr为PWM的频率,100HZ无闪烁,dc是PWM的占空比(高电平占的百分比)
  21. {
  22.         u32 tmp;
  23.         u16 heigh, low;
  24.         
  25.         tmp = SYSCLOCK/12;//一个机器周期频率
  26.         tmp = tmp / fr;  //一个机器周期中fr的频率所需计数值(包括高电平和低电平)
  27.         heigh = (tmp * dc) / 100;//高电平占dc%,所需计数值
  28.         low   = tmp - heigh;//低电平所需计数值
  29.         heigh = 65536-heigh;//高电平计数初值
  30.         low   = 65536-low;//低电平计数初值
  31.         
  32.         heighHR0 = (u8)(heigh >> 8);//高电平装入初值的高字节
  33.         heighLR0 = (u8)heigh;    //高电平装入初值的低字节
  34.         lowHR0   = (u8)(low >> 8);  //低电平装入初值的高字节
  35.         lowLR0   = (u8)low;    //低电平装入初值的低字节
  36.         
  37.         TMOD &= 0xF0;//清零T0控制位
  38.         TMOD |= 0x01;//设定T0工作方式1,16位可设定时器
  39.         TH0 = heighHR0;
  40.         TL0 = heighLR0;//装入高电平计数初值
  41.         PWMOUTLED = 1;//开始时PWM输出高电平
  42.         TR0 = 1;
  43.         ET0 = 1;
  44.         EA  = 1;
  45. }

  46. /*关闭PWM*/
  47. void PWM_Close()
  48. {
  49.         TR0 = 0;//关闭Timer0
  50.         ET0 = 0;//关闭T0中断
  51.         PWMOUTLED = 1;//PWM输出高电平
  52. }

  53. void main()
  54. {
  55.         u16 i=0;
  56.         int cont=0;
  57.         u8 fx=0;

  58.         while (1)     //呼吸灯效果
  59.         {
  60.                 if(fx==0)
  61.                 {
  62.                         cont+=10;
  63.                         if(cont>=90)
  64.                                 fx=1;        
  65.                 }
  66.                 else
  67.                 {
  68.                         cont-=10;
  69.                         if(cont<=0)
  70.                                 fx=0;        
  71.                 }
  72.                
  73.                
  74.                 //LED亮->暗
  75.                 PWM_Config(100, cont);//配置PWM频率为100HZ,占空比为10%
  76.                 for (i = 0; i < 30000; i++); //软件测试延时大约76ms

  77.                 PWM_Close();
  78.         }
  79. }


  80. /*定时器T0中断服务*/
  81. void Timer0_ISP() interrupt 1
  82. {
  83.         //判断PWM现在输出的是高电平还是低电平
  84.         if (PWMOUTLED)
  85.         {
  86.                 TH0 = lowHR0;
  87.                 TL0 = lowLR0;//装载低电平计数初值
  88.                 PWMOUTLED = 0;//PWM输出低电平
  89.         }
  90.         else
  91.         {
  92.                 TH0 = heighHR0;
  93.                 TL0 = heighLR0;//重装装载高电平计数初值
  94.                 PWMOUTLED = 1;//PWM输出高电平
  95.         }
  96. }


复制代码

回复

使用道具 举报

ID:332444 发表于 2021-2-25 16:45 | 显示全部楼层
回复

使用道具 举报

ID:419909 发表于 2021-3-1 11:43 | 显示全部楼层
呼吸灯就是调PWM,参考我之前分享的一个代码
/*********************************************************************/
可以调任意频率周期与占空比,工作原理就是一个周期的方波,将其分割成若干份,再根据高,低电平所占的份数来决定输出占空比。份数越多。占空比越精确。以下代码就是将一个周期内的方波分割成100份,用count累加,即count累加100次为一个周期,在这个周期内计数时,persent用于设置占空比。count数值小于persent时就输出高电平,不是就输出低电平,这个函数可以放在任意位置,要更精准,也可以放在定时器内执行。
主要代码:/***********************
count:用于计数。
persent: 设置占空比,值为1-100,这个可根据所设置的份数适当改变
PWM_OUT:用于输出PWM滤形的引脚。
***********************/
void Adj_PWM(unsigned int p)
{
static unsigned int count, persent;
persent=p;
if(count<100) count++;else count=0;  // 100以内累加。
if(count<=persent) PWM_OUT=1; else PWM_OUT=0; 设置占空比。即100份之中,高低电平所占的份数多少就是占空比数。
}
回复

使用道具 举报

ID:235055 发表于 2021-3-1 12:16 | 显示全部楼层
heighHR0 = (u8)(heigh >> 8);//高电平装入初值的高字节
heighLR0 = (u8)heigh; //高电平装入初值的低字节
其中,(u8)代表强制类型转换,把16位的heigh左移8位后也就是他原本的高八位取出,因为u8强制转换成8位数据,只取低八位,所以必须左移之和才能取出高八位,低八位只要直接强制类型转换就好了
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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