在线时间96 小时
UID3167208
注册时间2015-10-21
NXP金币0
TA的每日心情 | 开心 2019-3-22 20:15 |
---|
签到天数: 21 天 连续签到: 1 天 [LV.4]偶尔看看III
高级会员

- 积分
- 909
- 最后登录
- 2019-4-7
|

楼主 |
发表于 2017-3-21 11:48:32
|
显示全部楼层
本帖最后由 噬猎者 于 2017-3-21 11:58 编辑
我要分享-LPC541XX系列单片机寄存器快速配置历程
前些日子实在太忙了,现在把已投入使用的LPC54102单片机的通用型寄存器的快速配置分享给大家:
可能这次的会包含原帖的一些东西,具体涉及到具体的寄存器就不给大家讲解了,教会大家如何快速配置和使用吧!
1.LED灯测试(GPIO输出功能测试)-IOCON寄存器,GPIO寄存器
- void All_Init(void)//全部初始化
- {
- SysClock_Init();//时钟初始化
- LED_Init();//LED初始化
- Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_IOCON);// 禁能IOCON时钟,不关也可以,关了省电,还可以提高程序稳定性
- }
- void SysClock_Init(void)//时钟初始化
- {
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO0);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO1);
- }
- void LED_Init(void)//LED初始化
- {
- //LED_R P1-13
- //LED_G P1-12
- //LED_B P0-15
- PORT1_IOCON13 = 0x00000180;
- PORT1_GPIO_DIR |= 1UL << 13;
- LED_RED_OFF;
-
- PORT1_IOCON12 = 0x00000180;
- PORT1_GPIO_DIR |= 1UL << 12;
- LED_GREEN_OFF;
-
- PORT0_IOCON15 = 0x00000180;
- PORT0_GPIO_DIR |= 1UL << 15;
- LED_BLUE_OFF;
- }
复制代码 GPIO寄存器的管脚电平设置可参考LED的宏定义:
- //LED
- #define LED_R PORT1_OUT(13)
- #define LED_G PORT1_OUT(12)
- #define LED_B PORT0_OUT(15)
-
-
- #define LED_RED_OFF PORT1_GPIO_SET |= 1<<13
- #define LED_GREEN_OFF PORT1_GPIO_SET |= 1<<12
- #define LED_BLUE_OFF PORT0_GPIO_SET |= 1<<15
- #define LED_RED_ON PORT1_GPIO_CLR |= 1<<13
- #define LED_GREEN_ON PORT1_GPIO_CLR |= 1<<12
- #define LED_BLUE_ON PORT0_GPIO_CLR |= 1<<15
- #define LED_RED_TURN PORT1_GPIO_NOT |= 1<<13
- #define LED_GREEN_TURN PORT1_GPIO_NOT |= 1<<12
- #define LED_BLUE_TURN PORT0_GPIO_NOT |= 1<<15
复制代码 2.UART测试(UART 发送/接收/中断 功能测试)-USART0-3寄存器
- void All_Init(void)//全部初始化
- {
- SysClock_Init();//时钟初始化
- Uart_Init();//串口初始化
- Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_IOCON);// 禁能IOCON时钟,不关也可以,关了省电,还可以提高程序稳定性
- }
- void SysClock_Init(void)//时钟初始化
- {
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO0);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO1);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_USART1);//使能UASRT时钟
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_FRG);
- }
- void Uart_Init(void)//串口初始化
- {
- //UART_TXD P0-5 U1
- //UART_RXD P0-6 U1
- //使能管脚:
- PORT0_IOCON5 = 0x00000181;
- PORT0_IOCON6 = 0x00000181;
- UART1_CFG=0;//首先禁止通信
- UART1_CTL=0;//清除所有设置
- UART1_CFG |= 0x04UL;//设置8位数据,1位停止,无奇偶校验
- LPC_ASYNC_SYSCON->FRGCTRL = ((uint32_t) 0x7d << 8) | 0xFF;
- //波特率
- UART1_OSR = 0xd;
- UART1_BRG = 4;
- UART1_CFG |= 0x01u;// 配置完成允许通信
- //启动串口接收中断
- UART1_INTENSET = 0x01;
- UART1_CFG |= 0x0100u;//配置串口接收中断
- NVIC_ClearPendingIRQ(UART1_IRQn);//清除任何挂起的串口中断
- NVIC_EnableIRQ(UART1_IRQn);//使能串口接收中断
- NVIC_SetPriority(UART1_IRQn,1);//设置串口接收中断优先级
- }
复制代码 发送和接收请参考如下程序,由于printf属于FIRL中函数,就不给大家编写了,需要的可以询问我
- uint8 UART_getchar(void)//串口接收一个字符
- {
- while(!(UART1_STAT & 0x01)){}//等待接收机就绪
- return UART1_RXDAT;
- }
- void UART_putchar(uint8 num)//串口打印一个字符
- {
- while(!(UART1_STAT&0x04)){}// 等待发射机就绪
- UART1_TXDAT = num;
- }
- void UART_putbuff(uint8 *buff, uint32 len)//输出字符串数据
- {
- while(len--)
- {
- UART_putchar(*buff);
- buff++;
- }
- }
复制代码 3.按键测试(GPIO输入功能测试)-IOCON寄存器,GPIO寄存器
- void KEY_Init(void)//按键初始化
- {
- //KEY1-KEY6 P0-29 (注意23-28无内部上拉功能)
- //总线配置:输入上拉模式
- PORT0_IOCON9 = 0x00000190;
- PORT0_IOCON10 = 0x00000190;
- PORT0_IOCON11 = 0x00000190;
- PORT0_IOCON12 = 0x00000190;
- PORT0_IOCON13 = 0x00000190;
- PORT0_IOCON14 = 0x00000190;
- PORT0_GPIO_DIR &= ~(0x00007e00);//配置为输入模式
- }
复制代码- #define Read_DIP_SW1 PORT0_IN(3)//拨码开关1
- #define Read_DIP_SW2 PORT0_IN(2)//拨码开关2
- #define Read_DIP_SW3 PORT0_IN(7)//拨码开关3
复制代码 这个是以总线形式读取键值,需要并口读入的可以这样用
- #define READ_KEY_DATA ((PORT0_GPIO_PIN>>9)&0x3f)//获取键值(总线形式获取键值)
复制代码 4.PWM测试(SCT专用PWM输出功能测试)-SCT寄存器
- void All_Init(void)//全部初始化
- {
- SysClock_Init();//时钟初始化
- PWM_Init();//PWM初始化
- Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_IOCON);// 禁能IOCON时钟,不关也可以,关了省电,还可以提高程序稳定性
- }
- void SysClock_Init(void)//时钟初始化
- {
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO0);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO1);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_SCT0);
- Chip_SYSCON_PeriphReset(RESET_SCT0);
- }
复制代码- #define SETSCT_PWM 10000//10KHZ 100 000 000/计数频率 = SETSCT_PWM 这里包含着计数值 100 000 000 /10000 = 10000
- void PWM_Init(void)//PWM初始化
- {
- //Stop SCT
- SCT_CTRL_U = 0x00040004;//HALT_H HALT_L位 1 停止SCT
- //清除计数器
- SCT_CTRL_U |= 0x00080008;//CLRCTR_L CLRCTR_H
- SCT_REGMODE_L = 0;
- SCT_REGMODE_H = 0;
- SCT_MATCH0_U = 0;
- SCT_MATCHREL0_U = SETSCT_PWM;
- SCT_EVENT0_CTRL = 1 << 12;
- SCT_EVENT0_STATE = 1;
- /* Set SCT Counter to count 32-bits and reset to 0 after reaching MATCH0 */
- SCT_CONFIG = 0x00020001;//SCT_CONFIG_AUTOLIMIT_L SCT_CONFIG_32BIT_COUNTER
- //修改这里:
- // PWM:1.P1.3-sctout6 2.P1.4-sctout7 3.P1.2-sctout5 4.P1.1-sctout4
- PORT1_IOCON3 = 0x00000183;
- PORT1_IOCON4 = 0x00000183;
- PORT1_IOCON2 = 0x00000183;
- PORT1_IOCON1 = 0x00000183;
-
- SCTPWM_SetOutPin(1, 6);//定义PWM识别码(随意设置,不超过8个)
- SCTPWM_SetOutPin(2, 7);
- SCTPWM_SetOutPin(3, 5);
- SCTPWM_SetOutPin(4, 4);
- SCTPWM_SetDutyCycle(1,10000);//设置占空比
- SCTPWM_SetDutyCycle(2,10000);
- SCTPWM_SetDutyCycle(3,10000);
- SCTPWM_SetDutyCycle(4,10000);
- //启动SCT
- SCT_CTRL_U &= ~(0x00040004);//SCT_CTRL_HALT_L,SCT_CTRL_HALT_H
- }
- void SCTPWM_SetOutPin( uint8_t index, uint8_t pin)
- {
- ((SCT0_BASE_PTR)->EVENT[index].CTRL) = index | (1 << 12);
- ((SCT0_BASE_PTR)->EVENT[index].STATE) = 1;
- ((SCT0_BASE_PTR)->OUT[pin].SET) = 1;
- ((SCT0_BASE_PTR)->OUT[pin].CLR) = 1 <<index;
- SCT_RES = (SCT_RES & ~(3 << (pin << 1))) | (0x01 << (pin << 1));
- SCT_OUTPUTDIRCTRL = (SCT_OUTPUTDIRCTRL & ~(3 << (pin << 1)));
- }
- void SCTPWM_SetDutyCycle( uint8_t index, uint32_t ticks)
- {
-
- #if 1 //占空比0% - 输出0 占空比100% - 输出1
- ((SCT0_BASE_PTR)->MATCHREL[index].U) = ticks;
- #else //占空比0% - 输出1 占空比100% - 输出0
- if(ticks > SETSCT_PWM) ticks = SETSCT_PWM;
- ((SCT0_BASE_PTR)->MATCHREL[index].U) = SETSCT_PWM-ticks;
- #endif
- }
复制代码 5.定时器 中断测试(TIME通用型定时器功能测试)-CT32B0/1/2/3/4寄存器
- void All_Init(void)//全部初始化
- {
- SysClock_Init();//时钟初始化
- Time_Init();//定时器初始化
- Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_IOCON);// 禁能IOCON时钟,不关也可以,关了省电,还可以提高程序稳定性
- }
- void SysClock_Init(void)//时钟初始化
- {
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_INPUTMUX);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_IOCON);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO0);
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_GPIO1);
-
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_TIMER0);
- Chip_SYSCON_PeriphReset(RESET_TIMER0);
- }
- #define TIME_SET_MATCH 1//用来选择定时器的控制终端
- #define TIME_SET_RATE 12000//RATE = BOARD_EXTCLKINRATE/TICKRATE_HZ (12 000 000 HZ)/(1000HZ)
- void Time_Init(void)//定时器初始化
- {
- uint32_t reg;
- TIMER0_PR=0;//在PCLK时钟定时器设定预定值0
- //定时器复位控制
- reg = TIMER0_TCR;//禁用定时器,设置终端数为非0
- TIMER0_TCR = 0;
- TIMER0_TC = 1;
- TIMER0_TCR = 0x02;//软复位定时器计数器
- while (TIMER0_TC != 0) {}//等待终端计数清除
- TIMER0_TCR = reg;//恢复定时器状态
- //使定时器在时间匹配时产生中断,这里我们配置MR0
- TIMER0_MCR |= 1<<(TIME_SET_MATCH)*3;
- TIMER0_MR(TIME_SET_MATCH) = TIME_SET_RATE;//设置定时器时间
- //设置定时器在匹配发生时重新启动
- TIMER0_MCR |= 1<<((TIME_SET_MATCH) * 3 + 1);
- //启动定时器
- TIMER0_TCR |= 0x01;//Counter enable
- //清除任何挂起的中断的计时器
- NVIC_ClearPendingIRQ(CT32B0_IRQn);
- //使能定时器中断
- NVIC_EnableIRQ(CT32B0_IRQn);
- //配置定时器中断优先级
- NVIC_SetPriority(CT32B0_IRQn,2);
- /*
- 定时器中断配置:注意修改该项目数据
- if((TIMER0_IR & (1<<TIME_SET_MATCH))!=0)//中断信号检测
- { TIMER0_IR |= (1<<TIME_SET_MATCH);//清除中断信号
-
- }
- */
- }
复制代码- <font size="2">//定时器中断处理函数
- void CT32B0_IRQHandler(void)
- {
- if((TIMER0_IR & (1<<TIME_SET_MATCH))!=0)//中断信号检测
- { TIMER0_IR |= (1<<TIME_SET_MATCH);//清除中断信号
-
- }
- } </font>
复制代码
6.定时器 输入捕获测试(速度脉冲计数器(不启用触发中断))-CT32B0/1/2/3/4寄存器
(以下均需要开启对应时钟源)
- void Speed_InputCapture_Init(void)//速度脉冲计数初始化
- {//设置计数器为外部边沿触发计数器
- // P1-6 CT32B1_CAP2
- // P0-20 CT32B3_CAP0
- PORT1_IOCON6 &= ~0x07;//配置为输入捕获功能
- PORT1_IOCON6 |= 0x03;
-
- PORT0_IOCON20 &= ~0x07;//配置为输入捕获功能
- PORT0_IOCON20 |= 0x03;
- //1.定时器复位
- TIMER1_TCR = 0x02;//软复位定时器计数器
- //2.定时器设置
- TIMER1_CTCR = 0x02|((2)<<2);// Count Control Register 计数控制计数器
- //3.启动定时器
- TIMER1_TCR = 0x01;//Counter enable
-
- //1.定时器复位
- TIMER3_TCR = 0x02;//软复位定时器计数器
- //2.定时器设置
- TIMER3_CTCR = 0x02|((0)<<2);// Count Control Register 计数控制计数器
- //3.启动定时器
- TIMER3_TCR = 0x01;//Counter enable
-
- // TIMER1_TC ,TIMER3_TC反馈的是测速值
- }
复制代码
7.定时器 PWM输出测试-CT32B0/1/2/3/4寄存器
(以下均需要开启对应时钟源)
- #define ENGINE_PWM_Duty 1000 //周期计数大小
- #define ENGINE_PWM_Frequency 100 //PWM输出频率 Hz
- void Engine_PWM_Init(void)//舵机PWM输出控制初始化
- {
- // P0.14 CT32B2_MAT1
- //匹配时输出1 低于匹配值时输出0
- PORT0_IOCON14 &= ~0x07;
- PORT0_IOCON14 |= 0x03; //CT32B2_MAT1
-
- TIMER2_TCR = 0x02;//复位定时器
-
- TIMER2_PC = 0x00;
- TIMER2_PR = (uint16)(100000000/(ENGINE_PWM_Duty*ENGINE_PWM_Frequency))-1;//分频因子
- TIMER2_PWMC = 0X01<<(1);//设置 MATn 为PWM输出引脚
-
- TIMER2_MCR = 0x02<<0;//设置MR0匹配时复位TC,也就是把MR0当做周期寄存器
- TIMER2_MR(0) = ENGINE_PWM_Duty-1;//设置周期
- TIMER2_MR(1) = 90;//设置占空比MATn
- TIMER2_TCR = 0X01;//启动定时器
- //TIMER2_MR(1)修改舵机PWM,注意不要超过总的周期呀!尽量写个限幅
- }
复制代码 8.SysTick 计时器测试(CORE库)-SysTick寄存器(为了检查程序相应速度)
- void Timer_Start(void)//启动计时器
- {
- SysTick->CTRL = 0x1<<2; //SYSTICK使用内部时钟源
- SysTick->VAL = 0;//清空VAL值
- SysTick->LOAD = 10000000;//计数最大值
- SysTick->CTRL |= 0x1;//启动计时器
- }
- uint16 Get_Timer(void)//关闭计时器并获取计时器数据 ---uS
- {
- static uint16 Timer_Result;
- Timer_Result = SysTick->VAL;
- SysTick->CTRL &= ~(0x1);//关闭计时器
- Timer_Result = (10000000 - Timer_Result)/34;
- return Timer_Result;
- }
复制代码 9.ADC测试-ADC0寄存器
- #define ADC_RESOL_BIT 12 //12位ADC转换
- void ADC_Init(void)//ADC初始化
- {
- uint32 i=0;
- uint32_t ctrl;
- uint32_t tmp;
- //1.配置管脚功能(ADC管脚采用 模拟 )
- PORT0_IOCON29 = 0x01;//adc0
- // PORT1_IOCON1 = 0x01;//adc4
- // PORT1_IOCON2 = 0x01;//adc5
- // PORT1_IOCON3 = 0x01;//adc6
-
-
- //2.ADC配置
- Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_ADC0 | SYSCON_PDRUNCFG_PD_VDDA_ENA | SYSCON_PDRUNCFG_PD_VREFP);//启动ADC模块供电电源
- Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_ADC0);//开启ADC0时钟
- Chip_SYSCON_PeriphReset(RESET_ADC0);//复位ADC0
- SYSCON_BASE_PTR->ADCCLKSEL = (uint32_t) 0x00;
- SYSCON_BASE_PTR->ADCCLKDIV = 0x1;
- ADC_SEQA_CTRL = 0x00;
- ADC_SEQB_CTRL = 0x00;
- //配置ADC管脚:需要修改这个!!!
- ADC_SEQA_CTRL = (0x1<<0)|0xa0000000; // 信道11:0 |0xa0000000 启动信道0
-
- //ADC分辨率设置://3-12 2-10 1-8 0-6
- #if ADC_RESOL_BIT == 12
- ADC_CTRL = ((0x3)<<9)|0xFF;
- #elif ADC_RESOL_BIT == 10
- ADC_CTRL = ((0x2)<<9)|0xFF;
- #elif ADC_RESOL_BIT == 8
- ADC_CTRL = ((0x1)<<9)|0xFF;
- #else
- ADC_CTRL = ((0x0)<<9)|0xFF;
- #endif
- ADC_STARTUP = 0x1;
- for ( i = 0; i < 0x10; i++ ) {}
- //校准
- //1,设置ADC频率为30MHz
- ctrl = ADC_CTRL & 0x00007fff;
- tmp = ctrl;
- tmp &= ~(1 << 8);
- ADC_CTRL = tmp | 0x63;
- //2,启动校准
- ADC_CALIBR = 0x01;
- i = 0xF0000;
- while ( (ADC_CALIBR & 0x01) && --i );
- //3,设置频率为原频率
- ADC_CTRL = ctrl;
- //启动ADC
- ADC_STARTUP = 0x3;
-
- /*读取ADCn数据
- ADC_SEQA_CTRL|=0x1<<26;
- while ((ADC_DAT3 & 0x80000000U) ==0);// 等待转换完成
- ADC_Result = (ADC_DAT3>>4)&0xFFF;
- */
- }
复制代码 10.FPU测试-FPU的库我已经添加进去了,可以下载源代码查看,并测试运算速度
源代码:
工程源码.zip
(3.43 MB, 下载次数: 18)
|
|