STM32
直播中

ytrwv

8年用户 884经验值
擅长:EMC/EMI设计
私信 关注
[问答]

怎么实现基于STM32单片机流水灯仿真与程序设计?

怎么实现基于STM32单片机流水灯仿真与程序设计?

回帖(1)

周润艺

2021-11-23 11:57:09
本次程序设计和仿真是基于Proteus和keil的环境对STM32F103系列单片机进行流水灯设计,通过配置STM32的GPIO工作模式,实现LED的点亮和熄灭;通过配置8位流水灯程序设计,实现灯的流水实现。
关键字:Proteus、keil、STM32F103、GPIO
一、工程介绍

1.1、实现要求


  用STM32一个端口接8个发光二极管,编写程序,实现从左到右轮流点亮8个二极管(即流水灯)
二、仿真威廉希尔官方网站 设计

2.1、环境介绍


  仿真采用Proteus 8.9 SP2安装链接
2.2、威廉希尔官方网站 设计

第一步:在Proteus中的[P]选择所需要的零件有电阻RES、LED灯LED-GREEN最后还有单片机STM32F103R6





第二步:放置STM32F103R6单片机并设置VDDA、VSSA管脚以及NRST、VBAT和BOOT0
Design->Configure Power Rails ->Power Rails















第三步:放置八个LED
为什么LED接1K的电阻,这个可以参考链接2.2.2





三、STM32单片机GPIO口介绍

3.1、GPIO框图

GPIO总体分为7个部分:

  

  • 保护二极管及上、下拉电阻:保护二级管可以防止引脚外部过高或过低的电压输入
  • P-MOS 管和N-MOS 管:控制推挽输出和开漏输出
  • 输出数据寄存器:由输出数据寄存器GPIOX_ODR
  • 复用功能输出:STM32 的其它片上外设对GPIO 引脚进行控制
  • 输入数据寄存器:存储输入数据寄存器GPIOx_IDR
  • 复用功能输入:GPIO 引脚的信号传输到STM32 其它片上外设
  • 模拟输入输出:用于ADC 采集电压的输入通道






3.2、GPIO工作模式

GPIO 总共有8 种细分的工作模式
  
typedef enum
{
GPIO_Mode_AIN = 0x0,              // 模拟输入
GPIO_Mode_IN_FLOATING = 0x04,     // 浮空输入
GPIO_Mode_IPD = 0x28,             // 下拉输入
GPIO_Mode_IPU = 0x48,             // 上拉输入
GPIO_Mode_Out_OD = 0x14,          // 开漏输出
GPIO_Mode_Out_PP = 0x10,          // 推挽输出
GPIO_Mode_AF_OD = 0x1C,           // 复用开漏输出
GPIO_Mode_AF_PP = 0x18            // 复用推挽输出
} GPIOMode_TypeDef;
GPIOMode_TypeDef; 稍加整理可以大致归类为以下三类:


  • 输入模式(模拟/浮空/上拉/下拉)

  在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器GPIOx_IDR
读取I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉
输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外
部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于ADC 采集。


  • 输出模式(推挽/开漏)

  在输出模式中,推挽模式时双MOS 管以轮流方式工作,输出数据寄存器GPIOx_ODR
可控制I/O 输出高低电平。开漏模式时,只有N-MOS 管工作,输出数据寄存器可控制I/O
输出高阻态或低电平。输出速度可配置,有2MHz10MHz50MHz 的选项。此处的输出速
度即I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求
不严格,把速度设置成最大即可。
在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR
可读取I/O 的实际状态。


  • 复用功能(推挽/开漏)

  复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出
信号源于其它外设,输出数据寄存器GPIOx_ODR 无效;输入可用,通过输入数据寄存器
可获取I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。
通过对GPIO 寄存器写入不同的参数,就可以改变GPIO 的工作模式,再强调一下,
要了解具体寄存器时一定要查阅《STM32F10X-中文参考手册》中对应外设的寄存器说明。
在GPIO 外设中,控制端口高低控制寄存器CRH 和CRL 可以配置每个GPIO 的工作模式和
工作的速度,每4 个位控制一个IO,CRH 控制端口的高八位,CRL 控制端口的低8 位,
具体的看CRH 和CRL 的寄存器描述。
四、程序设计

4.1、环境介绍


  程序设计采用MDK 5.22安装链接
4.2、移位程序设计

/******************************************************************************
  * @brief  Water_LED:流水灯实现
******************************************************************************/
void Water_LED(void)
{
                unsigned  long int time = 0xFFFF;     //设置软件延时时间
                unsigned char Count = 0x00;           //设置流水起始地址
          unsigned char Stars = 0xFE;             //设置流水灯初始状态
                unsigned char Move = 0x01;            //设置移动补偿
                while((!((Count++)&0x08)))            //循环实现8位流水灯
                {
                        GPIOC->ODR = Stars;                //改变输出寄存器,改变端口状态
                        while(time--);                     //软件延时高电平持续实现
                        time = 0xFFFF;  
                        GPIOC->ODR = 0xFF;                 //消抖实现
                        Stars = (Stars<<1)|(Move);         //补偿实现
      // Stars = 0xFE (1111 1110B)左移一位为(1111 1100B)为了补偿最后一个0
      //Stars| Move =(1111 1100B)| 0000 0001B)=(1111 1101B)
                        Move = Move*2;                    //Move = (0000 0010B)
                        Move ++ ;                         //Move = (0000 0011B)
                        while(time--);                    //软件延时低电平持续时间
                        time = 0xFFFF;
                }
}
4.3、GPIO口设置


/******************************************************************************
  * @brief  Water_GPIO_Init:流水灯GPIO口初始化
******************************************************************************/
void Water_GPIO_Init(void)
{
        GPIO_InitTypeDef GPIO_OUT_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIO口时钟   
    GPIO_OUT_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
        //选择指定管脚
        GPIO_OUT_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;  //设置开漏输出
        GPIO_OUT_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;  //设置输出频率
        GPIO_Init(GPIOC,&GPIO_OUT_InitStructure);
        GPIOC->ODR = 0xFF;                                  //初始化后LED全熄灭
}
4.4、主程序设计
int main(void)
{
        SysClock_Configuration(RCC_PLLSource_HSI_Div2,RCC_CFGR_PLLMULL3);//设置系统时钟
        Water_GPIO_Init();                                               //流水灯GPIO口初始化
        while(1)
        Water_LED();                                                     //流水灯实现
}


五、结果分析与改进






1、流水程序设计是没有考虑GPIO8~15的状态,所以GPIOC高位以上的管脚要是用到其他功能,,可能会出问题
举报

更多回帖

发帖
×
20
完善资料,
赚取积分