384|5

820

帖子

3

资源

纯净的硅(初级)

【CH579M-R1】+开启定时器0控制LED闪烁及刷新LCD时间显示

    为了方便定时刷新LCD显示的日期时间,开始准备使用SysTick定时器来计数,但找了很久都不知道中断处理函数在哪,仅在CH57x_sys.c文件内找到一个获得SysTick当前计数值的函数,翻看数据手册也没有头绪,只好设置定时器0,将中断周期设置成100ms,然后在中断处理函数对计时变量加1,在main函数的主循环内进行判断处理。下图为测试过程:

time_01.jpg

    左上角左边的LED是呼吸灯,右边的LED按照权利1秒的周期闪烁,下面是动图效果:

my1_06.gif

    这是测试的代码:

/********************************** (C) COPYRIGHT *******************************
* File Name          : Main.c
* Author             : WCH
* Version            : 
* Date               : 2020/09/10
* Description 		 : 开发板测试
*******************************************************************************/

#include "CH57x_common.h"
#include "lcd_5110.h"
#include "ds1307.h"


UINT8 TxBuff[]="This is a tx exam\r\n";
UINT8 RxBuff[100];
UINT8 trigB;
UINT8 mode;
uint16_t year;              //年
uint8_t week,month,day,hour,minute,second,DS_Buff[8];//月日时分秒
volatile UINT16 time,ms;

int main()
{
    UINT8 i,dir,half,flag;
    
    
/* 配置串口1:先配置IO口模式,再配置串口 */   
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);			  // RXD-配置上拉输入
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);		// TXD-配置推挽输出,注意先让IO口输出高电平
    UART1_DefInit();
    
// 测试串口发送字符串
    UART1_SendString( TxBuff, sizeof(TxBuff) );

// 配置定时器0
    TMR0_TimerInit( FREQ_SYS/10 );                  // 设置定时时间 100ms
    TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END);          // 开启中断
    NVIC_EnableIRQ( TMR0_IRQn );

/* 配置LED和PWM */
    GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeOut_PP_5mA); // PA6 - PWM4(LED4)
    GPIOB_ModeCfg(GPIO_Pin_6, GPIO_ModeOut_PP_5mA); // PB6 - LED3
    PWMX_CLKCfg( 4 );
    PWMX_CycleCfg( PWMX_Cycle_64 );
	

    GPIOB_ModeCfg(GPIO_Pin_4, GPIO_ModeOut_PP_5mA); // PB4 - LED_G
    GPIOB_ModeCfg(GPIO_Pin_7, GPIO_ModeOut_PP_5mA); // PB7 - LED_Y
    GPIOB_InverseBits(4);

    LCD_init();           //LCD5110初始化
	display_main();       //显示主界面
	
	DS1307_Init();        //初始化DS1307模块
	DS1307_read_date();
	
	
    // 中断方式:接收数据后发送出去
    UART1_ByteTrigCfg( UART_7BYTE_TRIG );
    trigB = 7;
    UART1_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT );
    NVIC_EnableIRQ( UART1_IRQn );


    while(1)
    {
/*        //串口测试  查询方式:接收数据后发送出去
        len = UART1_RecvString(RxBuff);
        if( len )
        {
            UART1_SendString( RxBuff, len );            
        }
*/
		//PWM测试
        if(dir){
            i--;
            if(i == 0){
                dir = 0;
			    GPIOB_InverseBits(GPIO_Pin_4);
			}
        }
        else{
            i++;
            if(i == 64){
                dir = 1;
				GPIOB_InverseBits(GPIO_Pin_7);
			}
		}
        PWMX_ACTOUT( CH_PWM4, i, Low_Level, ENABLE);

//        PWMX_ACTOUT( CH_PWM7, 64-i, Low_Level, ENABLE);
        mDelaymS(10);
        //LED3闪烁测试
        time++;
        if(ms > 4){            //半秒处理
            ms = 0;
            GPIOB_InverseBits(GPIO_Pin_6);
            half++;
        }
		if(half>1){            //秒处理
		    second++;
			if(second > 59){
			    second = 0;
				DS1307_read_date();
			}
			display_time(hour,minute,second);
			half = 0;
			if(flag)           //轮换显示月日或年份
			    display_year(year);
			else
				display_date(month,day);
			flag++;
			if(flag > 1)
				flag = 0;
		}
    }
}


void UART1_IRQHandler(void)
{
    UINT8 i;
    
    switch( UART1_GetITFlag() )
    {
        case UART_II_LINE_STAT:        // 线路状态错误
            UART1_GetLinSTA();
            break;
        
        case UART_II_RECV_RDY:          // 数据达到设置触发点
            for(i=0; i!=trigB; i++)
            {
                RxBuff = UART1_RecvByte();
                UART1_SendByte(RxBuff);
            }
            break;
        
        case UART_II_RECV_TOUT:         // 接收超时,暂时一帧数据接收完成
            i = UART1_RecvString(RxBuff);
            UART1_SendString( RxBuff, i ); 
            break;
        
        case UART_II_THR_EMPTY:         // 发送缓存区空,可继续发送
            break;
        
        case UART_II_MODEM_CHG:         // 只支持串口0
            break;
        
        default:
            break;
    }
}

void TMR0_IRQHandler( void )        // TMR0 定时中断
{
    if( TMR0_GetITFlag( TMR0_3_IT_CYC_END ) )
    {
        TMR0_ClearITFlag( TMR0_3_IT_CYC_END );      // 清除中断标志
        GPIOB_InverseBits( GPIO_Pin_3 );        
    }
	ms++;
}

 


回复

1万

帖子

133

资源

管理员

个人签名

玩板看这里:

http://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!


回复

2557

帖子

1

资源

五彩晶圆(初级)

应该在.S或者对应的.C里面,需要自己填/

点评

是不是要在这个文件里添加SysTick中断处理函数的名称? [attachimg]500812[/attachimg]  详情 回复 发表于 2020-9-15 07:49
个人签名人已离开,无事别找,找也找不到。

回复

820

帖子

3

资源

纯净的硅(初级)

freebsder 发表于 2020-9-14 21:32 应该在.S或者对应的.C里面,需要自己填/

是不是要在这个文件里添加SysTick中断处理函数的名称?

systick_01.jpg

点评

不一定是在这里填,反正cortex支持C代码的链接,放在其他C文件里面就行了。只是函数名字你可以在这个文件里找。比如我手里的片子,名字是 SysTick_Handler .align 1 .thumb_func .weak SysT  详情 回复 发表于 2020-9-15 11:03

回复

2557

帖子

1

资源

五彩晶圆(初级)

hujj 发表于 2020-9-15 07:49 是不是要在这个文件里添加SysTick中断处理函数的名称?

不一定是在这里填,反正cortex支持C代码的链接,放在其他C文件里面就行了。只是函数名字你可以在这个文件里找。比如我手里的片子,名字是 SysTick_Handler

    .align 1
    .thumb_func
    .weak SysTick_Handler
    .type SysTick_Handler, %function
SysTick_Handler:
    ldr   r0,=SysTick_Handler
    bx    r0
    .size SysTick_Handler, . - SysTick_Handler

在其他C里面

viod SysTick_Handler(void)
{
    i++;
}

就可以了。

当然,不要忘了开启systick,cmsis代码里有,直接调用就好。

点评

    谢谢您!在startup_ARMCM0.s文件中找到了SysTick_Handler内容,如下图: [attachimg]500941[/attachimg]     下一步再尝试如何启用SysTick。  详情 回复 发表于 2020-9-15 18:30
个人签名人已离开,无事别找,找也找不到。

回复

820

帖子

3

资源

纯净的硅(初级)

freebsder 发表于 2020-9-15 11:03 不一定是在这里填,反正cortex支持C代码的链接,放在其他C文件里面就行了。只是函数名字你可以在这个文件 ...

    谢谢您!在startup_ARMCM0.s文件中找到了SysTick_Handler内容,如下图:

systick_02.jpg

    下一步再尝试如何启用SysTick。


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

关闭
站长推荐上一条 1/5 下一条

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表