51单片机点灯入门教程——2. 呼吸灯效果

2024-01-01 06:23:01
基本说明

本章使用芯片:STC8H8K64U核心板

芯片手册:点此查看

Keil 开发环境配置:点此查看

本章学习内容:利用库函数,开发C程序,实现呼吸灯效果。

代码实例

需求:使用串口来控制呼吸灯效果,如果串口接收的数据为1,则奇数灯亮;如为0,则偶数位灯亮。

#include "NVIC.h"
#include "GPIO.h"
#include "Config.h"
#include "Switch.h"
#include "STC8H_PWM.h"
#include "UART.h"
#include "Delay.h"


#define PEROID MAIN_Fosc/1000 //主频周期
#define LED_SW P45 //总开关接的P45引脚,要设置为低电平
#define LED1 P27
#define LED2 P26
#define LED3 P15
#define LED4 P14
#define LED5 P23
#define LED6 P22
#define LED7 P21
#define LED8 P20

PWMx_Duty duty;

void GPIO_Config(){
    GPIO_InitTypeDef init;
	init.Mode=GPIO_OUT_PP;//推挽输出
	init.Pin=GPIO_Pin_5;
    GPIO_Inilize(GPIO_P4, &init);

    init.Pin=GPIO_Pin_7 | GPIO_Pin_6 |GPIO_Pin_3 |GPIO_Pin_2 |GPIO_Pin_1 |GPIO_Pin_0 ;
    GPIO_Inilize(GPIO_P2, &init);

    init.Pin=GPIO_Pin_5 | GPIO_Pin_4;
    GPIO_Inilize(GPIO_P1, &init);

}

void UART_Config(){
    COMx_InitDefine init;
	init.UART_Mode = UART_8bit_BRTx;			
	init.UART_BRT_Use=BRT_Timer1;		
	init.UART_BaudRate=115200;		
	init.Morecommunicate=DISABLE;	
	init.UART_RxEnable=ENABLE;		
	init.BaudRateDouble=DISABLE;	
    UART_Configuration(UART1, &init);

    // UART会触发中断,所以要在NVIC中找到中断并配置优先级,URAT关系到写数据,所以优先级要高于其他任务
    NVIC_UART1_Init(ENABLE, Priority_3);
    // 切换引脚,本实验电路板默认就是PIN脚30、31 ,也可以不写,但有多组时必须配置
    UART1_SW(UART1_SW_P30_P31)	

}

void PWM_Config(){
    PWMx_InitDefine init;
    init.PWM_Mode=CCMRn_PWM_MODE1;			//模式,通常选择模式1或者模式2
	init.PWM_Period=PEROID-1;//周期时间,   0~65535	
	init.PWM_Duty=0;		//PWM占空比时间, 0~Period	
    init.PWM_DeadTime=0;	
    init.PWM_EnoSelect=ENO1P| ENO1N| ENO2P| ENO2N| ENO3P| ENO3N| ENO4P| ENO4N;		
    init.PWM_CEN_Enable=ENABLE;		
    init.PWM_MainOutEnable=ENABLE;
    // 配置PWMA和PWM1、PWM2、PWM3、PWM4
    PWM_Configuration(PWMA,&init);
    PWM_Configuration(PWM1,&init);
    PWM_Configuration(PWM2,&init);
    PWM_Configuration(PWM3,&init);
    PWM_Configuration(PWM4,&init);
    // 初始化PWMA的中断
    NVIC_PWM_Init(PWMA, DISABLE, Priority_0);
    //切换PWM引脚
    PWM1_SW(PWM1_SW_P20_P21);
    PWM2_SW(PWM2_SW_P22_P23);
    PWM3_SW(PWM3_SW_P14_P15);
    PWM4_SW(PWM4_SW_P26_P27);
}

void main(){
    int percent=0; //单片机中要使用的变量必须定义在离函数名最近的位置,否则编译时会报错未定义或重复定义
    int direction=1;
    EAXSFR(); //扩展寄存器访问使能, 使用PWM功能必须配置,且要配置在前面,否则可能无呼吸效果
    EA=1; //中断使能
    GPIO_Config();
    UART_Config();
    PWM_Config();
    // 总开关
    LED_SW=0;
    //点亮所有灯
    LED1 = LED2 = LED3 = LED4 = LED5 = LED6 = LED7 = LED8 = 0;
    while (1)
    {
        // 倒计时5次确保缓冲区内此时没正在接收数据
        if (COM1.RX_TimeOut>0 &&--COM1.RX_TimeOut==0){
            // 判断缓冲区有数据
            if (COM1.RX_Cnt>0){
                if (RX1_Buffer[0]==0){
                     direction=1;
                     } 
                else if (RX1_Buffer[0]==1)
                    {
                        direction=-1;
                    }
                // 让duty_percent一直在0-100来回往返
                if (percent>=100){
                    percent=100;
                }else if(percent<=0){
                    percent=0;
                }
                percent +=direction;
                // 修改PWM的duty并更新
                duty.PWM1_Duty=PEROID*percent/100;
                duty.PWM2_Duty=PEROID*percent/100;
                duty.PWM3_Duty=PEROID*percent/100;
                duty.PWM4_Duty=PEROID*percent/100;
                UpdatePwm(PWMA, &duty);
                //缓冲区数据拿完后要将数据长度置为0
                COM1.RX_Cnt=0;
                //设置延时
                delay_ms(250);
                delay_ms(250);
                }
            }
        }
    }
    

}

文章来源:https://blog.csdn.net/weixin_46157873/article/details/135271839
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。