stm32 时钟带日期显示与LED亮度调节

stm32 时钟带日期显示与LED亮度调节

开发板为正点原子stm32f103nano,基于综合测试实验例程改编。原本准备做计时器功能,但数码管只能显示到原例程的位数,做不出来。就改为保留原例程的RTC任务,ADC任务替换为日期显示,红外遥控任务改为存储数字到变量并把流水灯任务替换为按变量的值调节亮度。

代码如下(这里只给出main.c文件,复制到例程即可),具体说明见注释(被覆盖的程序的代码没有全部删去,请忽略)。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "includes.h"
#include "key.h"
#include "usart.h"
#include "malloc.h"
#include "smg.h"
#include "rtc.h"
#include "remote.h"
#include "beep.h"
#include "adc.h"
#include "24cxx.h"
#include "norflash.h"
#include "mass_mal.h"
#include "hw_config.h"
#include "memory.h"
#include "timer.h"
int a=0;
/UCOSII任务设置///
//START 任务
//设置任务优先级
#define START_TASK_PRIO      			10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE  				64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);

//ADC任务
//设置任务优先级
#define ADC_TASK_PRIO       			7
//设置任务堆栈大小
#define ADC_STK_SIZE  		    		64
//任务堆栈
OS_STK ADC_TASK_STK[ADC_STK_SIZE];
//任务函数
void adc_task(void *pdata);

//遥控任务
//设置任务优先级
#define REMOTE_TASK_PRIO    			6
//设置任务堆栈大小
#define REMOTE_STK_SIZE  		 		64
//任务堆栈
OS_STK REMOTE_TASK_STK[REMOTE_STK_SIZE];
//任务函数
void remote_task(void *pdata);

//流水灯任务
//设置任务优先级
#define LEDS_TASK_PRIO       		 	5
//设置任务堆栈大小
#define LEDS_STK_SIZE  				    64
//任务堆栈
OS_STK LEDS_TASK_STK[LEDS_STK_SIZE];
//任务函数
void leds_task(void *pdata);

//主任务
//设置任务优先级
#define MAIN_TASK_PRIO       			4
//设置任务堆栈大小
#define MAIN_STK_SIZE  					128
//任务堆栈
OS_STK MAIN_TASK_STK[MAIN_STK_SIZE];
//任务函数
void main_task(void *pdata);




//按键扫描任务
//设置任务优先级
#define KEY_TASK_PRIO       			2
//设置任务堆栈大小
#define KEY_STK_SIZE  					64
//任务堆栈
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数
void key_task(void *pdata);
//

OS_EVENT *msg_key;			//按键邮箱事件块

u8 key_event = 0; //按键事件 1:流水灯 2:RTC时钟 3:红外遥控 4:ADC采集 5:USB事件

//共阴数字数组
//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全灭
u8 smg_num[] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e, 0x01, 0x00};
u8 smg_duan = 0; //数码管段选
u8 smg_wei = 0; //数码管位选

//遥控按键
u8 remote_key = 0;
u8 num1 = 0;
u8 num = 0;

//ADC电压采样
u16 adcx = 0;
u16 adcx1 = 0;
float temp = 0;


//每2ms执行一次,用于扫描显示管
void TIM2_IRQHandler(void)//TIM2中断
{
    static u16 led_t = 0;

    if (__HAL_TIM_GET_IT_SOURCE(&TIM2_Handler, TIM_IT_UPDATE) != RESET) //检查指定的中断发生与否:TIM2中断源
    {
        __HAL_TIM_CLEAR_IT(&TIM2_Handler, TIM_IT_UPDATE);//清除TIMx的中断待处理位:TIM2中断源

        if (++led_t == 250) //500ms闪烁
        {
            led_t = 0;
            LED0 = !LED0;
        }

        if (key_event == 2) //RTC时钟
        {
            switch (smg_wei)
            {
                case 0:
                    smg_duan = smg_num[calendar.hour / 10];
                    break; //时

                case 1:
                    smg_duan = smg_num[calendar.hour % 10];
                    break;

                case 2:
                case 5:
                    smg_duan = 0x02;
                    break;

                case 3:
                    smg_duan = smg_num[calendar.min / 10];
                    break; //分

                case 4:
                    smg_duan = smg_num[calendar.min % 10];
                    break;

                case 6:
                    smg_duan = smg_num[calendar.sec / 10];
                    break; //秒

                case 7:
                    smg_duan = smg_num[calendar.sec % 10];
                    break;
            }
						
        }
        else if (key_event == 3) //红外遥控(在原例程基础上改为输入数字1到20并保存到变量a)
        {
					switch (remote_key)
            {
                case 104:
                    num1 = 0x00;
                    num = smg_num[1];
                    a=1;
                    break; //按键'1'

                case 152:
                    num1 = 0x00;
                    num = smg_num[2];
                    a=2;
                    break;     //按键'2'

                case 176:
                    num1 = 0x00;
                    num = smg_num[3];
                    a=3;
                    break;     //按键'3'

                case 48:
                    num1 = 0x00;
                    num = smg_num[4];
                    a=4;
                    break;      //按键'4'

                case 24:
                    num1 = 0x00;
                    num = smg_num[5];
                    a=5;
                    break;      //按键'5'

                case 122:
                    num1 = 0x00;
                    num = smg_num[6];
                    a=6;
                    break;     //按键'6'

                case 16:
                    num1 = 0x00;
                    num = smg_num[7];
                    a=7;
                    break;      //按键'7'

                case 56:
                    num1 = 0x00;
                    num = smg_num[8];
                    a=8;
                    break;      //按键'8'

                case 90:
                    num1 = 0x00;
                    num = smg_num[9];
                    a=9;
                    break;      //按键'9'

                case 66:
                    num1 = smg_num[1];
                    num = smg_num[0];
                    a=10;
                    break;      //按键'0'

                case 82:
                    num1 = smg_num[1];
                    num = smg_num[9];
                    a=19;
                    break;     //按键'DELETE'

                case 162:
                    num1 = smg_num[2];
                    num = smg_num[0];
                   a=20;
                    break;//按键'POWER'

                case 98:
                    num1 = smg_num[1];
                    num = smg_num[1];
                    a=11;
                    break;//按键'UP'

                case 226:
                    num1 = smg_num[1];
                    num = smg_num[2];
                    a=12;
                    break;//按键'ALIENTEK'

                case 34:
                    num1 = smg_num[1];
                    num = smg_num[3];
                    a=13;
                    break;//按键'LEFT'

                case 2:
                    num1 = smg_num[1];
                    num = smg_num[4];
                    a=14;
                    break;//按键'PLAY'

                case 194:
                    num1 = smg_num[1];
                    num = smg_num[5];
                    a=15;
                    break;//按键'RIGHT'

                case 224:
                    num1 = smg_num[1];
                    num = smg_num[6];
                    a=16;
                    break;//按键'VOL-'

                case 168:
                    num1 = smg_num[1];
                    num = smg_num[7];
                    a=17;
                    break;//按键'DOWN'

                case 144:
                    num1 = smg_num[1];
                    num = smg_num[8];
                    a=18;
                    break;//按键'VOL+'
            }

           

            switch (smg_wei)
            {
                case 0:
                case 1:
                case 2:
                case 3:
                    smg_duan = 0xff;
                    break;

                case 6:
                    if (num1) smg_duan = num1;
                    else     smg_duan = 0x00;

                    break;

                case 7:
                    smg_duan = num;
                    break;
            }
        }
               
        else if (key_event == 4) //日期显示
        {
            switch (smg_wei)
            {
                case 0:
                    smg_duan = smg_num[calendar.w_year/1000];
                    break; 

                case 1:
                    smg_duan = smg_num[calendar.w_year%1000/100];
                    break;

                case 2:
									smg_duan = smg_num[calendar.w_year%100/10];
                    break;
                case 3:
                    smg_duan = smg_num[calendar.w_year%10];
                    break;

                case 4:
                    smg_duan = smg_num[calendar.w_month/10];
                    break; 

                case 5:
                    smg_duan = smg_num[calendar.w_month%10];
                    break; 

                case 6:
                    smg_duan = smg_num[calendar.w_date/10];
                    break; //Ãë

                case 7:
                    smg_duan = smg_num[calendar.w_date%10];
                    break;
            }
        }

        if ((key_event > 1) && (key_event < 5))
        {
            LED_Write_Data(smg_duan, smg_wei); //数码管显示
            LED_Refresh();//刷新显示

            smg_wei++;

            if (key_event == 3)
            {
                if (smg_wei == 4) smg_wei = 6;
            }

            if (smg_wei > 7) smg_wei = 0;

        }

    }

}

//开始任务
void start_task(void *pdata)
{
    OS_CPU_SR cpu_sr = 0;
    pdata = pdata;
    msg_key = OSMboxCreate((void *)0);	//创建消息邮箱(按键)

    OSStatInit();					//初始化统计任务,会延时1秒左右
    OS_ENTER_CRITICAL();			//进入临界区(无法被中断打断)
    
    OSTaskCreate(adc_task, (void *)0, (OS_STK *)&ADC_TASK_STK[ADC_STK_SIZE - 1], ADC_TASK_PRIO); //ADC电压采集
    OSTaskCreate(leds_task, (void *)0, (OS_STK *)&LEDS_TASK_STK[LEDS_STK_SIZE - 1], LEDS_TASK_PRIO); //LED流水灯
    OSTaskCreate(key_task, (void *)0, (OS_STK *)&KEY_TASK_STK[KEY_STK_SIZE - 1], KEY_TASK_PRIO); //按键任务
    OSTaskCreate(remote_task, (void *)0, (OS_STK *)&REMOTE_TASK_STK[REMOTE_STK_SIZE - 1], REMOTE_TASK_PRIO); //遥控控制
    OSTaskCreate(main_task, (void *)0, (OS_STK *)&MAIN_TASK_STK[MAIN_STK_SIZE - 1], MAIN_TASK_PRIO); //消息邮箱检测任务
    OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务
    OS_EXIT_CRITICAL();				//退出临界区(可以被中断打断)
}

//ADC检测任务
void adc_task(void *pdata)
{
    while (1)
    {
        if (key_event == 4)
        {
            adcx = Get_Adc_Average(ADC_CHANNEL_9, 10); //ADC原始值
            temp = (float)adcx * (3.3 / 4096); //ADC电压值
            adcx1 = temp;
            temp -= adcx1;
            temp *= 1000;
        }

        delay_ms(100);
    }
}
#define swap16(x) (x&0XFF)<<8|(x&0XFF00)>>8	//高低字节交换宏定义
#define led_time 70  //延时时间(ms)
//根据a的值调节亮度
void leds_task(void *pdata)
{
    
srand(calendar.sec);
    while (1)
    {
        if (key_event == 1)
        {int c=a*50;
            			
						for(int b=0;b<1000;b++)
			   {
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); //LED0亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET); //LED1亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); //LED2亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET); //LED3亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET); //LED4亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET); //LED5亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET); //LED6亮
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); //LED7亮
					 delay_us(c);
					      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); //LED0灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); //LED1灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); //LED2灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); //LED3灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); //LED4灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET); //LED5灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET); //LED6灭
						    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET); //LED7灭
			   delay_us(1000-c);
				 }

        }

        delay_ms(15);
    }
}

//遥控器任务
void remote_task(void *pdata)
{
    while (1)
    {
        if (key_event == 3)
        {
            remote_key = Remote_Scan();
        }

        delay_ms(10);
    }
}


//主任务
void main_task(void *pdata)
{
    u32 key = 0;
    u8 err;
    u8 i = 0;
    u8 oldkey = 1;

    __HAL_TIM_ENABLE(&TIM2_Handler);//使能TIM2外设

    key = KEY1_PRES;
    OSMboxPost(msg_key, (void *)key); //发送消息

    while (1)
    {
        key = (u32)OSMboxPend(msg_key, 10, &err);

        if (key) BEEP = 1; //关闭蜂鸣器

        switch (key)
        {
            case KEY0_PRES://LED灯显示
                if (oldkey != key)
                {
                    oldkey = KEY0_PRES;
                    key_event = KEY0_PRES;
                    OSTaskSuspend(ADC_TASK_PRIO);	//挂起ADC任务
                    OSTaskSuspend(REMOTE_TASK_PRIO);	//挂起遥控任务
                    __HAL_TIM_DISABLE(&TIM2_Handler);//关闭计时器2(数码管显示)

                    for (i = 0; i < 8; i++)
                    {
                        LED_Write_Data(0x00, i); //数码管显示
                        LED_Refresh();//刷新显示
                    }

                    OSTaskResume(LEDS_TASK_PRIO);//恢复流水灯任务
                }

                break;

            case KEY1_PRES://启动RTC时钟显示
                if (oldkey != key)
                {
                    oldkey = KEY1_PRES;
                    key_event = KEY1_PRES;
                    OSTaskSuspend(ADC_TASK_PRIO);	//挂起ADC任务
                    OSTaskSuspend(REMOTE_TASK_PRIO);//挂起遥控器任务
                    __HAL_TIM_DISABLE(&TIM3_Handler);//关闭定时器3(遥控器检测)
                    smg_duan = 0x00;
                    smg_wei = 0;
                    OSTaskSuspend(LEDS_TASK_PRIO);	//挂起流水灯任务
                    HAL_GPIO_WritePin(GPIOC, 0xff, GPIO_PIN_SET); //关闭流水灯
                    __HAL_TIM_ENABLE(&TIM2_Handler);//启动计时器2(数码管显示)

                }

                break;

            case KEY2_PRES://启动遥控器控制
                if (oldkey != key)
                {
                    oldkey = KEY2_PRES;
                    key_event = KEY2_PRES;
                    OSTaskSuspend(ADC_TASK_PRIO);//挂起ADC任务
                    OSTaskSuspend(LEDS_TASK_PRIO);//挂起流水灯任务
                    HAL_GPIO_WritePin(GPIOC, 0xff, GPIO_PIN_SET); //关闭流水灯
                    __HAL_TIM_ENABLE(&TIM2_Handler);//关闭计时器2(数码管显示)
                    num1 = 0x00;
                    num = 0x00;
                    smg_wei = 0;
                    __HAL_TIM_ENABLE(&TIM3_Handler);//使能定时器3(遥控器检测)
                    OSTaskResume(REMOTE_TASK_PRIO);//恢复遥控器任务
                }

                break;

            case WKUP_PRES://启动ADC采集
                if (oldkey != key)
                {
                    oldkey = WKUP_PRES;
                    key_event = WKUP_PRES;
                    OSTaskSuspend(REMOTE_TASK_PRIO);//挂起遥控器任务
                    __HAL_TIM_DISABLE(&TIM3_Handler);//关闭定时器3(遥控器检测)
                    smg_duan = 0x00;
                    smg_wei = 0;
                    OSTaskSuspend(LEDS_TASK_PRIO);//挂起流水灯任务
                    HAL_GPIO_WritePin(GPIOC, 0xff, GPIO_PIN_SET); //关闭流水灯
                    OSTaskResume(ADC_TASK_PRIO);//恢复ADC任务
                    __HAL_TIM_ENABLE(&TIM2_Handler);//启动计时器2(数码管显示)
                }

                break;
        }


        delay_ms(10);
    }
}

//按键扫描任务
void key_task(void *pdata)
{
    u8 key;

    while (1)
    {
        key = KEY_Scan(0);

        if (key) OSMboxPost(msg_key, (void *)key); //发送消息

        delay_ms(5);
    }
}

//系统初始化
void system_init(void)
{
    u8 error = 0;
    HAL_Init();                    //初始化HAL库
    Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M
    delay_init(72);                 //初始化延时函数
    uart_init(115200);              //串口初始化115200
    LED_Init();		  	    //初始化LED
    KEY_Init();				//初始化按键
    BEEP_Init();            //初始化蜂鸣器
    mem_init();				//初始化内存池
    LED_SMG_Init();         //初始化数码管
    Remote_Init();          //红外遥控初始化
    Adc_Init();		  		//ADC初始化
    TIM2_Init(19, 7199);    //2ms定时显示
    printf("ALIENTEK NANO STM32F1 V1\r\n");
    printf("Copyright(C) 2018-2028\r\n");
    printf("HARDWARE: V2.00 ,SOFTWARE: V1.00\r\n");
    printf("CPU:STM32F103RBT6 72Mhz\r\n");
    printf("FLASH:128KB  SRAM:20KB\r\n");
    Norflash_Init();       //SPI初始化

   

    printf("RTC Check...\r\n");

    if (RTC_Init())        //RTC时钟初始化
    {
        printf("RTC Error!\r\n");
        LED6 = 0; //提升RTC错误
        error = 1;
    }
    else
    {
        printf("OK\r\n");
    }

    AT24CXX_Init();        //IIC初始化
    printf("24C02 Check...\r\n");

    if (AT24CXX_Check())
    {
        printf("24C02 Error!\r\n");
        LED7 = 0; //提示24C02错误
        error = 1;
    }
    else
    {
        printf("OK\r\n");
    }

    
    }




//主函数
int main(void)
{
    system_init();          //系统初始化
    OSInit();  	 			//初始化UCOSII
    OSTaskCreate(start_task, (void *)0, (OS_STK *)&START_TASK_STK[START_STK_SIZE - 1], START_TASK_PRIO ); //创建起始任务
    OSStart();	            //OS启动


}


 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路易斯720

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值