学习LPC17xx – RTC

2011-02-12 来自 · 一条评论 

  • 一开始时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 – 看门狗

2011-02-12 来自 · 留下评论 

看门狗能在芯片运行错误的时候复位系统。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

2011-02-12 来自 · 留下评论 

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

2011-02-12 来自 · 留下评论 

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

2011-02-12 来自 · 留下评论 

PWM和Timer类似,唯一不同的是它有6个输出匹配通道,而且可以配置为双边沿模式,即每路的PWM可以不是共边沿的。笔记、代码和输出效果如下:

  • PWM_ChannelConfig不能用在通道1上,因为通道1不可能作为双边沿输出。
  • PWM_Cmd仅使能PWM输出,PWM_CounterCmd才会启动定时器,才真正开始。


阅读更多

第 4 页 共 15 页« 首页...23456...10...末页 »