ARM⑦——WDT&RTC&PWM&ADC
一、看门狗概述
概述:看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗,一个输出到MCU的RST端,MCU正常工作的时候,每隔一端时间输出一个信号到喂狗端,给WDT清零,如果超过规定的时间不喂狗,(一般在程序包飞时),WDT定时超过,就回给出一个复位信号到MCU,是MCU复位。防止MCU死机,看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
工作原理:在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。
二、实现流程
原理图
无原理图,看门狗属于CPU内部机制
芯片手册
watchDog Timer
![]()
计数器计算:PCLK 100M/ (249+1)/128 = 3125; 1s复位 则设置WDDAT寄存器的值为3125
WTCNT 0x10060008 [15:8] 当前计数器的值
初始化函数#define WTCON (*(volatile unsigned int *)0x10060000) void watchdog_init() { WTCON = (WTCON & (~(0xff << 8))) | (0xf9 << 8); WTCON = WTCON | (0x1 << 5); WTCON = WTCON | (0x3 << 3); WTCON = WTCON & (~(0x1 << 2)); WTCON = WTCON | (0x1 << 0); WTCNT = (WTCNT & (~(0xffff << 0))) | 3125; }
喂狗函数#define WTCNT (*(volatile unsigned int *)0x10060008) void wdt_feed(int value) { WTCNT = value; }
三、RTC实时时钟
RTC概述:RTC实时时钟,记录年月日时分秒等数据,有备用电源,设备关闭后RTC也能正常记录时间。
秒寄存器
分寄存器
//RTC #define RTCCON (*(volatile unsigned int *)0x10070040) #define BCDSEC (*(volatile unsigned int *)0x10070070) #define BCDMIN (*(volatile unsigned int *)0x10070074) #define BCDHOUR (*(volatile unsigned int *)0x10070078) #define BCDDAYWEEK (*(volatile unsigned int *)0x10070080) #define BCDDAY (*(volatile unsigned int *)0x1007007C) #define BCDMON (*(volatile unsigned int *)0x10070084) #define BCDYEAR (*(volatile unsigned int *)0x10070088) void rtc_init() { RTCCON |= 1 << 0; BCDYEAR = 0x111; BCDMON = 0x11; BCDDAY = 0x11; BCDDAYWEEK = 0x2; BCDHOUR = 0x12; BCDMIN = 0x30; BCDSEC = 0x11; RTCCON &= ~(1<<0); } void rtc_display() { uart_sendChar(((BCDYEAR>>8)&0xf) + '0'); uart_sendChar(((BCDYEAR>>4)&0xf) + '0'); uart_sendChar(((BCDYEAR>>0)&0xf) + '0'); uart_sendChar('-'); uart_sendChar(((BCDMON>>4)&0x1) + '0'); uart_sendChar(((BCDMON>>0)&0xf) + '0'); uart_sendChar('-'); uart_sendChar(((BCDDAY>>4)&0x3) + '0'); uart_sendChar(((BCDDAY>>0)&0xf) + '0'); uart_sendChar('-'); uart_sendChar(((BCDHOUR>>4)&0x3) + '0'); uart_sendChar(((BCDHOUR>>0)&0xf) + '0'); uart_sendChar(':'); uart_sendChar(((BCDMIN>>4)&0x7) + '0'); uart_sendChar(((BCDMIN>>0)&0xf) + '0'); uart_sendChar(':'); uart_sendChar(((BCDSEC>>4)&0x7) + '0'); uart_sendChar(((BCDSEC>>0)&0xf) + '0'); uart_sendChar('\r'); uart_sendChar('\n'); }
四、PWM
PWM:脉冲宽度调制占空比:就是输出的pwm中,高电平保持的事件与该pwm的时钟周期的时间之比
上述例子,TCNTB寄存器 存放的初值用来倒数 ,当TCNTB 比 TCMPB寄存器值大时,输出的是低电平,当TCNTB倒数到小于等于TCMPB时 电平反转为高电平,直到计数到0,之后又开始新一轮的倒数计数,从而实现PWM和占空比的控制。
利用无源蜂鸣器测试PWM
原理图
PWM BEEP ——》MOTOR_PWM ——》XpwmTOUT0/LCD_FRM/GPD0_0
芯片手册
寄存器 地址 bit位 值 备注 GPD0CON 0x114000A0 [3:0] 0x2 = TOUT0 使能复用PWMTOUT功能 TCNTB0 0x139D000C [31:0] 300 倒数计数器预装载值 TCMPB0 0x139D0010 [31:0] 150 比较值 TCFG0 0x139D0000 [7:0] 249 (250 - 1) timer0、1的预分频值 TCFG1 0x139D0004 [3:0] 0100 = 1/16 timer0的分频值 TCON 0x139D0008 [3] 1 = auto reload timer0自动装载 [2] 1 = output 使能pwm输出 [1] 1 or 0 = update 启动 / 关闭更新,与[0]启动定时器不能同时开启 [0] 1 or 0 启动 、关闭定时器 编程
#define GPD0CON (*(volatile unsigned int *)0x114000A0) #define TCFG0 (*(volatile unsigned int *)0x11400000) #define TCFG1 (*(volatile unsigned int *)0x11400004) #define TCON (*(volatile unsigned int *)0x11400008) #define TCNTB0 (*(volatile unsigned int *)0x1140000C) #define TCMPB0 (*(volatile unsigned int *)0x11400010) //初始化蜂鸣器 pwm void pwm_beep_init() { GPD0CON = (GPD0CON & (~(0xf << 0))) | (0x2 << 0); TCFG0 = TCFG0 & (~(0xff << 0)) | (249 << 0); TCFG1 = TCFG0 & (~(0xf << 0)) | (0x4 << 0); TCON = (TCON & (~(0xf << 0))) | (0xe << 0); TCNTB0 = TCNTB0 | 300; TCMPB0 = TCMPB0 | 150; } void beep_start() { TCON = TCON & ~(0x1 << 1); TCON = TCON | (0x1 << 0); }
五、ADC
1、原理图
ADC——》VR1——》XadcAIN3
2、芯片手册
XadcAIN3
寄存器 地址 bit 值 备注 ADCCON 0x126C0000 [16] 0x1 12位的A/D转换位(位数越高精度越高) [15] --- 获取转换是否结束 [14] 0x1 使能预分频 [13:6] 0x1 预分频值 [2] 0x0 普通模式 [1] 0x0 失能阅读模式 [0] 0x1 开始读取数据(不能与[1]同时打开),搭配[15]一起使用 ADCDLY 0x126C0008 [15:0] --- 读取延时,配合ADCCON[1]使用 ADCDAT 0x126c000c [11:0] --- ADC转换的值 ADCMUX 0x126c001c [3:0] 0010 选择AIN3 3、编程
//ADC #define ADCCON (*(volatile unsigned int *)0x126c0000) #define ADCDAT (*(volatile unsigned int *)0x126c000c) #define ADCMUX (*(volatile unsigned int *)0x126c001c) void adc_init() { ADCCON = ADCCON | (0x1 << 16); //12位数据 ADCCON = ADCCON | (0x1 << 14); //允许预分频 ADCCON = ADCCON & (~(0xff << 6)) | (132 << 6); //132+1预分频值 ADCCON = ADCCON & (~(0x1 << 2)); //正常工作模式 ADCCON = ADCCON & (~(0x1 << 1)); //disables start ADCCON = ADCCON & (~(0x3 << 0)) | (0x3 << 0); } int adc_read() { ADCCON = ADCCON | (0x1 << 0); //开始转换 while(ADCCON&(0x1<<15) == 0); //未转换完成 return (ADCDAT & (0xfff << 0)); }

京公网安备 11010502036488号