学习LPC17xx – RTC
- 一开始时RTC走的特别慢,而且时间间隔不确定,可能是由于某些复位值不确定。
- 一些复位值不确定的寄存器可能要另外初始化(不确定)
#include <lpc17xx.h> #include <stdint.h> #include "lpc17xx_libcfg.h" #include <debug_frmwrk.h> #include <lpc17xx_rtc.h> uint32_t _DGETNUM(uint8_t cnt) { uint32_t rtn = 0; while(cnt--) { rtn = rtn * 10 + (_DG - '0'); } return rtn; } RTC_TIME_Type rtctim; void readrtctim() { _DBG("Second : "); rtctim.SEC = _DGETNUM(2); _DBD32(rtctim.SEC); _DBG_(""); _DBG("Minute : "); rtctim.MIN = _DGETNUM(2); _DBD32(rtctim.MIN); _DBG_(""); _DBG("Hour : "); rtctim.HOUR = _DGETNUM(2); _DBD32(rtctim.HOUR); _DBG_(""); _DBG("D of M : "); rtctim.DOM = _DGETNUM(2); _DBD32(rtctim.DOM); _DBG_(""); _DBG("D of W : "); rtctim.DOW = _DGETNUM(2); _DBD32(rtctim.DOW); _DBG_(""); _DBG("D of Y : "); rtctim.DOY = _DGETNUM(3); _DBD32(rtctim.DOY); _DBG_(""); _DBG("Month : "); rtctim.MONTH = _DGETNUM(2); _DBD32(rtctim.MONTH); _DBG_(""); _DBG("Year : "); rtctim.YEAR = _DGETNUM(4); _DBD32(rtctim.YEAR); _DBG_(""); _DBG_("**********************************************************************"); } void writertctim() { _DBG("Second : "); _DBD32(rtctim.SEC); _DBG_(""); _DBG("Minute : "); _DBD32(rtctim.MIN); _DBG_(""); _DBG("Hour : "); _DBD32(rtctim.HOUR); _DBG_(""); _DBG("D of M : "); _DBD32(rtctim.DOM); _DBG_(""); _DBG("D of W : "); _DBD32(rtctim.DOW); _DBG_(""); _DBG("D of Y : "); _DBD32(rtctim.DOY); _DBG_(""); _DBG("Month : "); _DBD32(rtctim.MONTH); _DBG_(""); _DBG("Year : "); _DBD32(rtctim.YEAR); _DBG_(""); _DBG_("**********************************************************************"); } int main(void) { char cmd; uint32_t ch; debug_frmwrk_init(); _DBG_("RTC Test Time(S to set and G to Get), Reg(W to write and R to read)"); RTC_Init(LPC_RTC); RTC_ResetClockTickCounter(LPC_RTC); RTC_Cmd(LPC_RTC, ENABLE); RTC_CalibCounterCmd(LPC_RTC, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_SECOND, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_MINUTE, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_HOUR, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_DAYOFWEEK, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_DAYOFMONTH, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_DAYOFYEAR, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_MONTH, DISABLE); RTC_CntIncrIntConfig(LPC_RTC, RTC_TIMETYPE_YEAR, DISABLE); while(1) { cmd = _DG; switch(cmd) { case 'S': readrtctim(); RTC_SetFullTime(LPC_RTC, &rtctim); break; case 'G': RTC_GetFullTime(LPC_RTC, &rtctim); writertctim(); break; case 'W': _DBG("Channel : "); ch = _DGETNUM(1); _DBD(ch); _DBG_(""); RTC_WriteGPREG(LPC_RTC, ch, _DGETNUM(10)); _DBD32(RTC_ReadGPREG(LPC_RTC, ch)); _DBG_(""); break; case 'R': _DBG("Channel : "); ch = _DGETNUM(1); _DBD(ch); _DBG_(""); _DBD32(RTC_ReadGPREG(LPC_RTC, ch)); _DBG_(""); break; } } } |
学习LPC17xx – 看门狗
看门狗能在芯片运行错误的时候复位系统。LPC17xx的看门狗提供了一个“中断模式”,当看门狗超时时进入中断。然而这个中断不能被关闭,而且实际应用的时候不应该使用中断模式,仅是为了调试方便。
- 若设置成中断模式,那么中断标志不能被软件清零,除非复位。要禁用中断,需要在NVIC中关闭。中断模式的作用就是为了调试看门狗,不让器件复位。
代码通过触发一个外部中断让程序进入死循环而不能正常喂狗,而迫使看门狗复位。
#include <lpc17xx.h> #include "lpc17xx_libcfg.h" #include <debug_frmwrk.h> #include <lpc17xx_gpio.h> #include <lpc17xx_nvic.h> #include <lpc17xx_systick.h> #include <stdint.h> #include <lpc17xx_exti.h> #include <lpc17xx_pinsel.h> #include <lpc17xx_wdt.h> volatile uint8_t led7; volatile uint32_t SysTickCnt; void EINT3_IRQHandler(void) { _DBG_("Int Triggered"); //dead here while(1); } void SysTick_Handler(void) { SysTickCnt++; } int main(void) { uint32_t prv; uint8_t i; PINSEL_CFG_Type pincfg; debug_frmwrk_init(); _DBG_("System Start/Reset"); GPIO_SetDir(2, 0x000000FF, 1); GPIO_SetDir(2, 1 << 11, 0); SYSTICK_InternalInit(10); //the maximum value should not exceed the 24 bit systick counter SYSTICK_Cmd(ENABLE); SYSTICK_IntCmd(ENABLE); GPIO_IntCmd(2, 1 << 10, 0); pincfg.Portnum = PINSEL_PORT_2; pincfg.Pinnum = PINSEL_PIN_10; pincfg.Funcnum = PINSEL_FUNC_0; pincfg.Pinmode = PINSEL_PINMODE_PULLUP; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); NVIC_SetPriority(SysTick_IRQn, 0); NVIC_SetPriority(EINT3_IRQn, 1); NVIC_EnableIRQ(EINT3_IRQn); WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET); WDT_Start(100000); while(1) { for(i = 0; i <= 7; ++ i) { GPIO_SetValue(2, 1 << i); prv = SysTickCnt; while(SysTickCnt - prv < 10); GPIO_ClearValue(2, 1 << i); WDT_Feed(); } } } |
学习LPC17xx – DAC
LPC17xx的DAC操作比较简单。除此外它还支持DMA访问,所以可能可以方便的合成数字信号。
- 若没有选择对应的引脚,那么DAC不会启动,对其寄存器访问会产生硬错误
代码:从0开始,每0.1秒将DAC的值增加1,同时采集ADC的值输出到串口。只要将DAC输出和ADC输入连接,就可以看到采样值。
#include <lpc17xx.h> #include "lpc17xx_libcfg.h" #include <debug_frmwrk.h> #include <lpc17xx_nvic.h> #include <lpc17xx_pinsel.h> #include <lpc17xx_dac.h> #include <lpc17xx_adc.h> #include <lpc17xx_systick.h> //#include <core_cm3.h> volatile int SysTickCnt; void SysTick_Handler(void) { SysTickCnt++; } int main(void) { PINSEL_CFG_Type pincfg; int prv; int cur = 0; debug_frmwrk_init(); _DBG_("DAC Test"); //PWM Pins and Channels pincfg.Portnum = PINSEL_PORT_0; pincfg.Pinnum = PINSEL_PIN_26; pincfg.Funcnum = PINSEL_FUNC_2; pincfg.Pinmode = PINSEL_PINMODE_TRISTATE; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); DAC_Init(LPC_DAC); DAC_UpdateValue(LPC_DAC, (1 << 10) - 1); SYSTICK_InternalInit(10); //the maximum value should not exceed the 24 bit systick counter SYSTICK_Cmd(ENABLE); SYSTICK_IntCmd(ENABLE); pincfg.Portnum = PINSEL_PORT_1; pincfg.Pinnum = PINSEL_PIN_31; pincfg.Funcnum = PINSEL_FUNC_3; pincfg.Pinmode = PINSEL_PINMODE_TRISTATE; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); ADC_Init(LPC_ADC, 200000); ADC_ChannelCmd(LPC_ADC, 5, ENABLE); ADC_BurstCmd(LPC_ADC, ENABLE); ADC_StartCmd(LPC_ADC, ADC_START_CONTINUOUS); while(1) { while(!ADC_ChannelGetStatus(LPC_ADC, 5, 1)); _DBD16(ADC_ChannelGetData(LPC_ADC, 5)); _DBG_(""); prv = SysTickCnt; while(SysTickCnt < prv + 10); cur = (cur + 1) & ((1 << 10) - 1); DAC_UpdateValue(LPC_DAC, cur); } } |
学习LPC17xx – ADC
LPC17xx的ADC可以工作于两种模式:软件突发模式和自动模式。软件突发模式下,每一次转换都需要软件去触发。自动模式下,ADC会自动去转换选定的通道,并可选的触发中断。以下代码分别为软件突发和自动转换。
- Burst模式指的是由硬件自动控制,非Burst每次必须手动Start。
- 时钟频率不能超过200,000 Hz
#include <lpc17xx.h> #include "lpc17xx_libcfg.h" #include <debug_frmwrk.h> #include <lpc17xx_nvic.h> #include <lpc17xx_pinsel.h> #include <lpc17xx_adc.h> volatile int SysTickCnt; void SysTick_Handler(void) { SysTickCnt++; } int main(void) { int prv; PINSEL_CFG_Type pincfg; SYSTICK_InternalInit(10); //the maximum value should not exceed the 24 bit systick counter SYSTICK_Cmd(ENABLE); SYSTICK_IntCmd(ENABLE); debug_frmwrk_init(); _DBG_("ADC Test"); pincfg.Portnum = PINSEL_PORT_1; pincfg.Pinnum = PINSEL_PIN_31; pincfg.Funcnum = PINSEL_FUNC_3; pincfg.Pinmode = PINSEL_PINMODE_TRISTATE; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); ADC_Init(LPC_ADC, 200000); ADC_ChannelCmd(LPC_ADC, 5, ENABLE); ADC_BurstCmd(LPC_ADC, DISABLE); while(1) { ADC_StartCmd(LPC_ADC, ADC_START_NOW); while(!ADC_ChannelGetStatus(LPC_ADC, 5, 1)); _DBD16(ADC_ChannelGetData(LPC_ADC, 5)); _DBG_(""); prv = SysTickCnt; while(SysTickCnt < prv + 10); } } |
#include <lpc17xx.h> #include "lpc17xx_libcfg.h" #include <debug_frmwrk.h> #include <lpc17xx_nvic.h> #include <lpc17xx_pinsel.h> #include <lpc17xx_adc.h> volatile int SysTickCnt; void SysTick_Handler(void) { SysTickCnt++; } int main(void) { int prv; PINSEL_CFG_Type pincfg; SYSTICK_InternalInit(10); //the maximum value should not exceed the 24 bit systick counter SYSTICK_Cmd(ENABLE); SYSTICK_IntCmd(ENABLE); debug_frmwrk_init(); _DBG_("ADC Test"); pincfg.Portnum = PINSEL_PORT_1; pincfg.Pinnum = PINSEL_PIN_31; pincfg.Funcnum = PINSEL_FUNC_3; pincfg.Pinmode = PINSEL_PINMODE_TRISTATE; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); pincfg.Portnum = PINSEL_PORT_0; pincfg.Pinnum = PINSEL_PIN_26; pincfg.Funcnum = PINSEL_FUNC_1; pincfg.Pinmode = PINSEL_PINMODE_TRISTATE; pincfg.OpenDrain = PINSEL_PINMODE_NORMAL; PINSEL_ConfigPin(&pincfg); ADC_Init(LPC_ADC, 200000); ADC_ChannelCmd(LPC_ADC, 3, ENABLE); ADC_ChannelCmd(LPC_ADC, 5, ENABLE); ADC_BurstCmd(LPC_ADC, ENABLE); ADC_StartCmd(LPC_ADC, ADC_START_CONTINUOUS); while(1) { while(!ADC_ChannelGetStatus(LPC_ADC, 5, 1)); _DBD16(ADC_ChannelGetData(LPC_ADC, 5)); _DBG_(" : Channel 5"); while(!ADC_ChannelGetStatus(LPC_ADC, 3, 1)); _DBD16(ADC_ChannelGetData(LPC_ADC, 3)); _DBG_(" : Channel 3"); prv = SysTickCnt; while(SysTickCnt < prv + 10); } } |
学习LPC17xx – PWM
PWM和Timer类似,唯一不同的是它有6个输出匹配通道,而且可以配置为双边沿模式,即每路的PWM可以不是共边沿的。笔记、代码和输出效果如下:
- PWM_ChannelConfig不能用在通道1上,因为通道1不可能作为双边沿输出。
- PWM_Cmd仅使能PWM输出,PWM_CounterCmd才会启动定时器,才真正开始。


