找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3235|回复: 5
收起左侧

stm32使用寄存器做一个流水灯

[复制链接]
ID:945385 发表于 2021-6-28 11:23 | 显示全部楼层 |阅读模式
使用寄存器方式,用stm32做一个流水灯。
硬件:stm32f103R6,一个按键,5个LED灯。
功能:按键可以实现左移、右移、从中间往两边移动。

原理图:
1.png

波形仿真:
  1. 代码:
  2. #include "stm32f10x.h"


  3. /**
  4.   * @brief  延时函数
  5.   * @param  time :X ms
  6.   * @retval none
  7.   */
  8. void delay_ms(u16 time)
  9. {   
  10.    u16 i=0;  
  11.    while(time--)
  12.    {
  13.       i=12000;  //自己定义
  14.       while(i--) ;   
  15.    }
  16. }

  17. /**
  18.   * @brief  LED初始化
  19.   * @param  none
  20.   * @retval none
  21.   */
  22. void LED_Init(void)
  23. {
  24.         RCC->APB2ENR|=1<<4;    //使能PORTC时钟                    
  25.         GPIOC->CRL &= 0xFFF00000;
  26.         GPIOC->CRL |= 0x00033333;//PC0-PC4 推挽输出
  27.         
  28.     GPIOC->ODR |= 0x0000001F;      //PC0-PC4 输出高,灯关闭状态                                                                          
  29. }

  30. /**
  31.   * @brief  按键初始化
  32.   * @param  none
  33.   * @retval none
  34.   */
  35. void KEY_Init(void)
  36. {
  37.         RCC->APB2ENR|=1<<3;                    //使能PORTB时钟
  38.         GPIOB->CRL &= 0xFFFFF000;
  39.         GPIOB->CRL |= 0x00000888;        //PB0-PB2 上拉输入
  40.         GPIOB->ODR |= 1<<0;
  41. }

  42. /**
  43.   * @brief  流水灯左移
  44.   * @param  none
  45.   * @retval none
  46.   */
  47. void LED_MoveLeft(void)
  48. {
  49.         GPIOC->ODR |= 0x0000001F;      //灯全部关闭
  50.         delay_ms(10);
  51.         
  52.         GPIOC->ODR &= 0xFFFFFFEF;           //右边第一个LED亮
  53.         delay_ms(10);
  54.         
  55.         GPIOC->ODR &= 0xFFFFFFF7;           //右边第二个LED亮
  56.         delay_ms(10);
  57.         
  58.         GPIOC->ODR &= 0xFFFFFFFB;           //右边第三个LED亮
  59.         delay_ms(10);
  60.         
  61.         GPIOC->ODR &= 0xFFFFFFFD;           //右边第四个LED亮
  62.         delay_ms(10);
  63.         
  64.         GPIOC->ODR &= 0xFFFFFFFE;           //右边第五个LED亮
  65.         delay_ms(10);
  66. }

  67. /**
  68.   * @brief  流水灯右移
  69.   * @param  none
  70.   * @retval none
  71.   */
  72. void LED_MoveRight(void)
  73. {
  74.         GPIOC->ODR |= 0x0000001F;      //灯全部关闭
  75.         delay_ms(10);
  76.         
  77.         GPIOC->ODR &= 0xFFFFFFFE;           //右边第五个LED亮
  78.         delay_ms(10);
  79.         
  80.         GPIOC->ODR &= 0xFFFFFFFD;           //右边第四个LED亮
  81.         delay_ms(10);
  82.         
  83.         GPIOC->ODR &= 0xFFFFFFFB;           //右边第三个LED亮
  84.         delay_ms(10);
  85.         
  86.         GPIOC->ODR &= 0xFFFFFFF7;           //右边第二个LED亮
  87.         delay_ms(10);
  88.         
  89.         GPIOC->ODR &= 0xFFFFFFEF;           //右边第一个LED亮
  90.         delay_ms(10);
  91. }

  92. /**
  93.   * @brief  流水灯从中间往两边移动
  94.   * @param  none
  95.   * @retval none
  96.   */
  97. void LED_MoveToSide(void)
  98. {
  99.         GPIOC->ODR |= 0x0000001F;      //灯全部关闭
  100.         delay_ms(10);
  101.         
  102.         GPIOC->ODR &= 0xFFFFFFFB;           //中间灯亮
  103.         delay_ms(10);
  104.         
  105.         GPIOC->ODR &= 0xFFFFFFF1;           //中间灯亮
  106.         delay_ms(10);
  107.         
  108.         GPIOC->ODR &= 0xFFFFFFE0;           //最外灯亮   
  109.         delay_ms(10);        
  110. }

  111. /**
  112.   * @brief  主函数
  113.   * @param  none
  114.   * @retval none
  115.   */
  116. int main(void)
  117. {        
  118.         u16 t;
  119.         static u8 i=0;
  120.         LED_Init();                //LED初始化
  121.         KEY_Init();                //按键初始化
  122.         
  123.         while(1)
  124.         {
  125.                 t=GPIOB->IDR;
  126.                 if(!(t & 0x0001))
  127.                 {
  128.                         i++;
  129.                         if(i>3)
  130.                                 i=0;
  131.                         switch(i)
  132.                         {
  133.                                 case 1: LED_MoveLeft();//左移
  134.                                         break;
  135.                                 case 2:        LED_MoveToSide();//两边移
  136.                                         break;
  137.                                 case 3:LED_MoveRight();//右移
  138.                                         break;
  139.                                 default:break;
  140.                         }
  141.                 }
  142.                 //若要使用keil的逻辑示波器,取消延时注释,更方便观测波形
  143.                 //delay_ms(200);        //延时200ms
  144.         }
  145. }

复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:927615 发表于 2021-6-29 12:03 来自手机 | 显示全部楼层
现在主要芯片太贵
回复

使用道具 举报

ID:927615 发表于 2021-6-29 12:04 来自手机 | 显示全部楼层
能不能用8脚芯片做?
回复

使用道具 举报

ID:857869 发表于 2021-6-30 18:10 | 显示全部楼层
能不能用8脚芯片做?
回复

使用道具 举报

ID:927615 发表于 2021-6-30 22:23 来自手机 | 显示全部楼层
编译出错,不会搞呀
回复

使用道具 举报

ID:766282 发表于 2021-7-4 12:16 | 显示全部楼层
能不能用8脚芯片做?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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