时钟产生单元:CGU
系统振荡器:外部振荡器
IRC振荡器:内部振荡器
看门狗振荡器:
倍频之前的时钟:sys_pllclkin
倍频之后的时钟:sys_pllclkout
主时钟源选择寄存器:MAINCLKSEL
PLL倍频
LPC1114发挥最大性能,选择PLL后的时钟,SYSCON->MAINCLKSEL = 0x00000003; // 主时钟选择PLL后的时钟
SYSPLLCLKSEL:系统倍频时钟源选择寄存器,0-1位:00 选择IRC振荡器。01 系统振荡器
10选择看门狗震荡器。11保留。
SYSCON->SYSPLLCLKSEL = 0x00000001;//PLL时钟源选择系统振荡器
SYSAHBCLKDIV:系统AHB时钟分频器,除了给AH提供时钟,还给内核存储器以及APB提供时钟。给这个寄存器写0,LPC1114就不工作了,写1就是LPC1114的时钟就是主时钟除以1.这个寄存器用8位:一般我们写SYSCON->SYSAHBCLKDIV = 0x01;//AHB时钟分频值为1.
UART:串行异步收发器。与PC机进行信息的收发。
SPI:通用串行同步收发器
SYSAHBCLKCTRL:系统外围时钟配置寄存器,它管理着LPC1114几乎所有的独立模块的时钟开启与关闭。
问题1:采集数据间隔时间
由于采集环境数据(温度、湿度、光度、三轴加速度、电量)时间间隔较长,不适合环境实时监控。
解决方案:修改系统定时器SysTick
将Tick的判断值减小,同时将time_counter0的判断值改到最小,由于M0主程序用while轮询,执行语句需要时间,所以将采集数据的时间和其它时间计数器时间稍微有区别,采集数据间隔不需要做到每秒采集,所以采集数据的时间在其它时间计数器中的间隔最长,将近1秒采集一次。
M0内核处理器LPC1114时钟倍频最高能到50MHZ,
CGU时钟配置图
IRC振荡器:内部RC振荡器,12MHZ时钟振荡器
系统振荡器:外部振荡器
Sys_pllclkin:倍频之前的时钟
Sys_pllclkout:倍频之后的时钟
MAINCLKSEL:主时钟源选择寄存器
00 选择IRC振荡器
01选择输入到PLL之前的时钟
10选择看门狗振荡器
11选择PLL之后的时钟
系统默认的情况下是选择IRC振荡器作为系统的主时钟,为了让PLL1114发挥最大的性能,选择PLL后的时钟作为主时钟。
SYSPLLCLKSEL :系统倍频时钟源选择寄存器
00 选择IRC振荡器
01 选择系统振荡器
10 选择看门狗振荡器
11保留
系统默认的情况下是选择IRC振荡器作为PLL输入时钟源,但是我们外部安插了精确的12MHZ晶振,所以选择外部12M晶振01作为时钟源
AHB:高性能总线,用于高性能模块之间的连接。
SYSAHBCLKDIV:系统AHB时钟分频器,不仅给AHB(LPC1114的AHB只有GPIO)提供时钟,还给内核存储器以及APB提供时钟。给这个寄存器写0,LPC1114就不工作了,写1,LPC1114的系统时钟就是主时钟除以1
SYSPLLCLKUEN是PLL时钟源更新允许寄存器,要想实现更新,必须对该寄存器先写0,在写1.
SYSCON->SYSPLLCLKUEN = 0x00;
SYSCON->SYSPLLCLKUEN = 0x01;更新
SYSPLLCTRL是系统倍频控制寄存器,通过它可以确定倍频的倍数。0-4位确定M值,5和6位确定P值。在普通模式下,PLL输出频率的公式是
Fclkout=M*Fclkin=(FCCO)/(2*p)
在普通模式下,输出频率实际上是有FCCO产生的,为了能让PLL正常工作,FCCO需要在156-320MHZ之间。现在PLL的输出频率为12MHZ,LPC1114允许最大工作频率是50MHZ,因此我们只能把它倍频到48MHZ。所以,M=4.根据数据手册P的值可以为1,2,,4,8.这里只有当P=2的时候FCCO的值为48*2*2=192,在156-320之间。所以M=4,P=2.
SYSPLLSTAT是倍频状态寄存器,专门用来看PLL有没有锁定,是一个只读寄存器。
掉电配置寄存器:写1掉电 写0上电
int main(void)
{
SysCLK_config();
//使能GPIO时钟
SYSCON->SYSAHBCLKCTRL |= (1<<6);
//把P1.9 P1.10 设置为输出
GPIO1->DIR |= (1<<9);
GPIO1->DIR |= (1<<10);
while(1)
{
//关闭LED1 LED2
GPIO1->DATA |= (1<<9);
GPIO1->DATA |= (1<<10);
delay_ms(1000);
//打开LED1 LED2
GPIO1->DATA &= ~(1<<9);
GPIO1->DATA &= ~(1<<10);
delay_ms(1000);
}
}
当我们需要配置引脚功能复用时 需要先开启IOCON时钟 再复用引脚
//使能IOCON时钟
SYSCON->SYSAHBCLKCTRL |= (1<<16);
IOCON->PIO0_0 &= ~0x07;//低三位清零 再赋值
IOCON->PIO0_0 |= 0x02;
看门狗:基本作用是在单片机由于不明原因产生错误时程序跑飞,不能及时喂狗而使单片机自动复位。
看门狗寄存器有4个:
WDT->MOD:看门狗模式选择寄存器
WDT->TC:看门狗定时器值
WDT->FEED看门狗喂狗寄存器
WDT->TV看门狗当前值寄存器(一般不用)
1 模式寄存器(M0):模式一:在定时时间内没有喂狗,复位LPC1114
WDT->MOD |= 0X03
模式二:在定时时间内没有喂狗,进入看门狗中断服务函数 WDT->MOD |= 0X01(设置为中断模式)
NVIC_EnableRQ(WDT_IRQn)(开启看门狗中断)
2 定时器值寄存器(TC)
这是一个完整的32位寄存器,该值可以是0-0xFFFFFFFF,不过对该寄存器写入的值小于255时,LPC1114会自动把该值写入255(0xFF)
这是一个倒计时定时器,倒计时到0时,将置位模式寄存器MOD当中的2和3位。2位是看门狗超时标志WDTOF,3位是看门狗中断标志位WDINT。
3 喂狗寄存器(FEED)
喂狗时序为:先写0xAA在写0x55
WDT_CLK_Setup:1看门狗振荡器时钟上电;2设置频率;3选择看门狗时钟源;4更新时钟源(先写0 再写1);5等待更新成功;6设置看门狗分频值
PWM:1使能IOCON时钟;2设置GPIO复用;3禁止IOCON时钟;4复位定时器;5设置预分频寄存器;6设置PWM输出引脚;7设置周期寄存器;8设置周期及占空比;9启动定时器
SysTick:系统定时器,基本作用是为操作系统服务的,与其他定时器不同的是他是24位的倒计时定时器。
static volatile uint32 TimeTick = 0;
void SysTick_Handler(void) //系统定时器中断服务程序
{
TimeTick++;
}
void delay_ms(uint32 ms)
{
SYSTICK->STRELOAD = (((24000)*ms)-1); //往重载计数器里写值
SYSTICK->STCURR = 0; //计数器清零
SYSTICK->STCTRL |= ((1<<1)|(1<<0)); //开启计数器 开启中断
while(!TimeTick);
TimeTick = 0;
SYSTICK->STCTRL =0; //关闭计数器
}
1入口参数的范围 用的时候不要超过这个范围(定时器位数)
2如果超过范围 须多次使用定时器
3 不要在中断中使用,此函数是用中断实现的,嵌套中断比较麻烦,不能进行有效设置
串口UART:universal asynchronous receiver transmitter,即通用串行异步收发器。一般的串口有两个作用,一是和电脑通讯,另一个是控制一些串转并的芯片,现在大多数芯片都改成SPI控制或I2C控制,。
void UARTInit(uint32_t baudrate)
{
uint32_t Fdiv;
uint32_t regVal;
UARTTxEmpty = 1;
UARTCount = 0;
NVIC_DisableIRQ(UART_IRQn);
LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */
LPC_IOCON->PIO1_7 &= ~0x07;
LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */
/* Enable UART clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
regVal = LPC_SYSCON->UARTCLKDIV;
Fdiv = ((SystemAHBFrequency/regVal)/16)/baudrate ; /*baud rate */
LPC_UART->DLM = Fdiv / 256;
LPC_UART->DLL = Fdiv % 256;
LPC_UART->LCR = 0x03; /* DLAB = 0 */
LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
/* Read to clear the line status. */
regVal = LPC_UART->LSR;
/* Ensure a clean start, no data in either TX or RX FIFO. */
while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
while ( LPC_UART->LSR & LSR_RDR )
{
regVal = LPC_UART->RBR; /* Dump data from RX FIFO */
}
/* Enable the UART Interrupt */
NVIC_EnableIRQ(UART_IRQn);
#if TX_INTERRUPT
LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */
#else
LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */
#endif
return;
}
配置引脚时先清空原来的状态 再写入新数据
1设置RX TX 2 使能时钟 3 设置时钟分频值 4 8位传输1个停止位无奇偶校验位 5 计算该波特率要求的除数锁存寄存器值 6 写锁存器高低位 7 禁止对锁存器的访问 8 允许FIFO 9 读UART状态寄存器
启动串口中断方式:先开总中断 再开串口中断
GPIO控制寄存器:IOCON->PIOx_x是“引脚配置寄存器”,选择引脚具体复用那
个功能。
I2Cinit 1 使能I2C模块;2使能I2C时钟;3使能IOCON时钟;4配置GPIO位
I2C功能;5禁止IOCON功能;6 I2C通信7 清标志位8 使能I2C接口
GPIO->DIR是当引脚作为通用输入输出口时,该引脚作为输出还是输入脚,写0
为输入引脚,写1为输出引脚,默认情况下该寄存器为0,作为输入引脚。
GPIO->DATA是“数据寄存器”,控制引脚电平高低,当作为输入引脚喝死读寄
存器就可以知道引脚的电平,当作为输出引脚时,写寄存器可以控制引脚的电平
高低。
Seg7led:7段数码管
SPI:SD卡的通道接口之一。SD卡有两种通信接口,分别是SD模式和SPI模式
,SD模式的读写数据比SPI模式快很多。但是LPC1114只有SPI。
DHT11:温湿度模块。包括一个电阻式感湿元件和一个NTC测温元件,并与一个
高性能8位单片机相连接。
引脚说明:VDD供电3.5-5.5V DC
DATA 串行口数据,单总线
GND 接地,电源负极
NC 空脚
单总线:只有一个数据线,系统中的数据交换,控制均有单总线完成。一次传送40位数据高位先出。
8位湿度整数数据+8位湿度小数数据+8位温度整数数据+8位温度小数数据+8位校验位
示例:接收到的40位数据为:
0011 0101 0000 0000 0001 1000 0000 0000 0100 1101
湿度高8位 湿度低8位 温度高8位 温度低8位 校验位
计算:
0011 0101+0000 0000+0001 1000+0000 0000= 0100 1101
接收数据正确:
湿度:0011 0101=35H=53%RH
温度:0001 1000=18H=24℃
数据时序图:用户主机(MCU)发送一次开始信号后,DHT11从低功耗模式转换到高速模式,待主机开始信号结束,DHT11发送响应信号,送出40位的数据,并触发一次信息采集。
主机读取的温湿度数据总是前一次的测量值,如果两次测量间隔时间很长,请连续读两次,以第二次获得的值为实时的温湿度值
外设读取步骤:1 、DHT11上电(等待一秒,越过不稳定状态在此期间不能发送任何命令),测试环境温湿度数据,并记录。同时DHT11的DATD数据线保持高电平,此时DATA引脚处于输入状态,时刻监测外部信号。
2、主机IO设置为低电平,低电平的时间不能小于18MS,给从机发送起始信号,然后拉高。
3、DHT11监测到外部信号有低电平的时候,等待外部低电平结束,DHT11输出80微秒的低电平作为应答信号,紧接着输出80微秒的高电平通知外设准备接受数据,微处理器的IO此时处于输入状态,检测到IO有低电平后,等待80微秒的高电平后的数据接受。
4、由DHT11的DATA引脚输出40位数据,微处理器根据IO电平变化接收40位
数据。
5、结束信号:DHT11的DATA引脚输出40位数据后,继续输出低电平50微秒后
转入输入状态。DHT11内部重测环境温湿度数据,并记录,等待外部信号的到来。
ADCinit:1ADC模块上电;2使能ADC时钟;3使能IOCON时钟;4设置GPIO;
关闭IOCON时钟;5选择ADC输入通道;6设置采样时钟频率;7设置扫描模式;
8 位数模式;
SCL 线是高电平时,SDA 线从高电平向低电平切换,这个情况表示起始条件;
SCL 线是高电平时,SDA 线由低电平向高电平切换,这个情况表示停止条件。
起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态
起始和停止条件
芯片的时序图:
当CLK高电平的时候,如果SDA产生下降沿,则说明数据传输开始,
在CLK为高电平的时候传输数据,首先传主机、从机的address,然后在传数据。当在CLK处于高电平的时候,如果SDA产生了上升沿,说明传输结束。