




已阅读5页,还剩28页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
电设工作小结之MSP430G2553 学习笔记 1 一,MSP430G2553 单片机的各个功能模块 (一),IO 口模块, 1,我们所用的 MSP430G2553 有两组 IO 口,P1 和 P2。 2,IO 口的寄存器有:方向选择寄存器 PxDIR,输出寄存器 PxOUT,输入寄存器 PxIN,IO 口内部上拉或下拉电阻使能寄存器 PxREN, IO 口功能选择寄存器 PxSEL 和 PxSEL2,IO 口中断使能寄存器 PxIE,中断沿选择寄存器 PxIES,IO 口中断标志寄存器 PxIFG。 3,所有的 IO 都带有中断,其中所有的 P1 口公用一个中断向量,所有的 P2 口公用一个 中断向量。所以在使用中断时,当进入中断后,还要判断到底是哪一个 IO 口产生的中断, 判断方法可以是判断各个 IO 口的电平。 4,中断标志 PxIFG 需要软件清除,也可以用软件置位,从而用软件触发一个中断。 注意:在设置 PxIESx 时根据 PxINx 有可能会引起相应的 PxIFGx 置位(具体的情况见用户 指南),所以在初始化完 IO 口中断以后,正式使用 IO 中断前要先将对应的 PxIFGx 清零。 程序如下: void IO_interrupt_init() /IO 中断初始化函数 P1REN |= BIT4+BIT5+BIT6+BIT7; / pull up 内部上拉电阻使能 /使用中断时,使能内部的上拉电阻这样当该脚悬空是,电平不会跳变,防止悬空时电 平跳变不停的触发中断 P1OUT = BIT4+BIT5+BIT6+BIT7; / 当引脚上的上拉或下拉电阻使能时,PxOUT 选择 是上拉还是下来 /0:下拉,1:上拉 P1IE |= BIT4+BIT5+BIT6+BIT7; / interrupt enabled P13 中断使能 P1IES |= BIT4+BIT5+BIT6+BIT7; / Hi/lo edge 下降沿中断 /P1IES /上升沿触发中断 P1IFG /中断标志位清零 5,PxOUT:如果引脚选择了内部的上拉或下拉电阻使能,则 PxOUT 设定电阻是上拉 还是下拉,0:下拉,1:上拉 6,当 IO 口不用时,最好不要设为输入,且为浮动状态(这是 IO 口的默认状态), 因为当输入为浮动时,输入电压有可能会在 VIL 和 VIH 之间,这样会产生击穿电流。所以 不用的 IO 口可以设为输出状态,或设为输入状态但通过外围电路接至 VCC 或 GND,或接 一个上拉/下拉电阻。 7,当使用 msp430g2553 的 IO 口时要注意,因为 g2553 的 IO 口寄存器的操作,不像 51,它不能单独针对某一位进行操作,必须对整个寄存器进行操作。所以就不像 51,g2553 不可以定义 bit 型的数据。所以在使用 msp 的 IO 口时要注意对需要位的操作, 而不要影响其他无关的位,可以 用 | /RS = P2.0 #define SET_RS P2OUT|=BIT0; #define CLR_RW P2OUT /RW = P2.1 #define SET_RW P2OUT|=BIT1; #define CLR_EN P2OUT /EN = P2.2 #define SET_EN P2OUT|=BIT2; #define DataPort P1OUT 8,g2553 的 P27 和 P26 脚分别接外部晶体的输出和输入脚 XOUT 和 XIN,默认是自 动设为了晶振管脚功能,但是当想把它们用为普通的 IO 时,也可以,设置对应的 SEL 设 为普通的 IO 即可,如下: P2DIR |= BIT6+BIT7; /把 P26 和 P27 配置为普通 IO 并为输出脚 默认为晶振的 输入和输出引脚 作为 dac0832 的 P2SEL /cs 和 wr 控制端 P2SEL2 (二),时钟系统 1,msp430 能做到超低功耗,合理的时钟模块是功不可没的。但是功能强大的时钟模 块设置起来也相对复杂一些。 2,msp430 的时钟源有: (1),外接低频晶振 LFXT1CLK:低频模式接手表晶体 32768Hz,高频模式 450KHz8MHz; (2),外接高速晶振 XT2CLK:8MHz ; (3),内部数字控制振荡器 DCO:是一个可控的 RC 振荡器,频率在 016MHz; (4),超低功耗低频振荡器 VLO:不可控,420KHz 典型值为 12KHz; 3,时钟模块:430 的时钟模块有 MCLK SMCLK ACLK : (1),主系统时钟 MCLK:提供给 MSP430 的 CPU 时钟。可以来自 LFXT1CLK XT2CLK DCO VLO 可选,默认为 DCO。 (2),子系统时钟 SMCLK: 提供给高速外设。可以来自 LFXT1CLK XT2CLK DCO VLO 可选,默认为 DCO。 (3),辅助系统时钟 ACLK:提供给低速外设。可来自 LFXT1CLK VLO。 4,内部的振荡器 DCO 和 VLO 提供的时钟频率不是很精确,随外部环境变化较大。 DCO 默认的频率大概为 800KHz,但我用示波器观察的为 1.086MHz 左右,当 DCO 设置的 过高时,用示波器可以看到波形不再是方波,而是类似于正弦波。DCO 可以用 CCS 提供 的宏定义进行相对比较精确的设置,如下: DCOCTL = CALDCO_12MHZ; /DCO 设为 12MHz 这种方法设 DCO 频率比较精确,实际测 得为 12.08MHz 左右 正弦波 BCSCTL1 = CALBC1_12MHZ; 用这种方法可以设置 1,8,12,16MHz 宏定义如下: #ifndef _DisableCalData SFR_8BIT(CALDCO_16MHZ); SFR_8BIT(CALBC1_16MHZ); SFR_8BIT(CALDCO_12MHZ); SFR_8BIT(CALBC1_12MHZ); SFR_8BIT(CALDCO_8MHZ); SFR_8BIT(CALBC1_8MHZ); SFR_8BIT(CALDCO_1MHZ); SFR_8BIT(CALBC1_1MHZ); #endif 5,使用超低功耗低频振荡器 VLO 可以很大程度地降低系统功耗,下面的例子是设置 ACLK 为 VLO,MCLK 为 VLO 的 8 分频: #include /1 延时 /#define CPU_F (double)16000000)/cpu frequency16000000 #define CPU_F (double)1630)/cpu frequency1630 /CPU 的实际 MCLK 大 约为 13.05/8=1.63KHz #define delay_us(x) _delay_cycles(long)(CPU_F*(double)x/1000000.0) #define delay_ms(x) _delay_cycles(long)(CPU_F*(double)x/1000.0) void main(void) volatile unsigned int i; / Volatile to prevent r emoval WDTCTL = WDTPW + WDTHOLD; / Stop watchdog timer BCSCTL3 |= LFXT1S_2; / LFXT1 = VLO 低频时钟 选择为 VLO ACLK 选为 VLO IFG1 / Clear OSCFault flag 清除振荡器错误中断标志 _bis_SR_register(SCG1 + SCG0); / Stop DCO SCG1 禁止 SMCLK SCG0 禁止 DCO BCSCTL2 |= SELM_3 + DIVM_3; / MCLK = LFXT1/8 /因为前面已经选择了 LFXT1 = VLO 所以 MCLK 选为 VLO 8 分频 所以 CPU 的 MCLK 大约为 1.5KHz P1DIR = 0xFF; / All P1.x outputs P1OUT = 0; / All P1.x reset P2DIR = 0xFF; / All P2.x outputs P2OUT = 0; / All P2.x reset P1SEL |= BIT0+BIT4; / P10 P14options 功能选择为外 围模块 /p10 输出 ACLK,来自 VLO,p14 输出 SMCLK, 因为禁止了 SMCLK,所以 P14 脚 无波形输出 /VLO 典型值为 12KHz 实际用示波器测得为:13.05KHz 左右波动 /所以 CPU 的实际 MCLK 大约为 13.05/8=1.63KHz for (;) P1OUT = BIT6; / P1.6 闪烁 delay_ms(1000); 6,如上面的程序所示,其中的延迟函数用那种方法,使用系统的延迟周期函数 _delay_cycles(int n); 可以达到比较精确的延迟,如下: /more_ /1 延时 /#define CPU_F (double)16000000)/cpu frequency16000000 #define CPU_F (double)12000000)/cpu frequency12000000 #define delay_us(x) _delay_cycles(long)(CPU_F*(double)x/1000000.0) #define delay_ms(x) _delay_cycles(long)(CPU_F*(double)x/1000.0) /2 空函数 #define nop() _NOP(); 7,系统上电后默认使用的是 DCO 时钟,DCO 默认的频率大概为 800KHz,但我用示波 器观察的为 1.086MHz 左右,当 DCO 设置的过高时,用示波器可以看到波形不再是方波, 而是类似于正弦波。 (三),定时器 Timer_A 1,MSP430g2553 具有两个 16 位的定时器:Timer0_A Timer1_A。分别具有三个捕捉/ 比较寄存器,具有输入捕捉,输出比较功能。可以产生定时中断,也可以产生 PWM。 2,产生 PWM,例子如下: #include void Timer_A0_1_init() /TA0.1 输出 PWM TACTL|= TASSEL_1+MC_1;/ACLK,增计数 CCTL1=OUTMOD_7;/输出模式为复位/ 置位 CCR0=328;/时钟频率为 32768HZ,100HZ /CCR1=164;/时钟频率为 32768HZ,占空比 CCR1/CCR0=50% CCR1=109;/占空比 CCR1/CCR0=1/3 TA0.1 由 P1.2 P1.6 输出 void Timer_A1_2_init() /TA1.2 输出 PWM TA1CTL|= TASSEL_1+MC_1;/ACLK,增计数 TA1CCTL2=OUTMOD_7;/输出模式为复位/置位,注意 CCTL2 要写为 TA1CCTL2 TA1CCR0=164;/时钟频率为 32768HZ,波形 32768/CCR0=199HZ TA1CCR2=41;/占空比 CCR2/CCR0=1/4,注意 CCR2 要写成 TA1CCR2 TA1.2 由 P2.4 P2.5 输出 void Timer_A1_1_init() /TA1.1 输出 PWM TA1CCTL1=OUTMOD_7; TA1CCR1=123; /占空比 CCR1/CCR0=3/4,注意 CCR1 要写成 TA1CCR1 TA1.1 由 P2.1 P2.2 输出 void IO_init() P1SEL|=BIT2+BIT6; P1DIR|=BIT2+BIT6;/P1.2 P1.6 输出 TA0.1 OUT1 P2SEL|=BIT4+BIT5; P2DIR|=BIT4+BIT5;/P2.4 P2.5 输出 TA1.2 OUT2 P2SEL|=BIT1+BIT2; P2DIR|=BIT1+BIT2; /P2.1 P2.2 输出 TA1.1 OUT1 void main(void) WDTCTL=WDTPW+WDTHOLD; IO_init(); Timer_A0_1_init(); Timer_A1_2_init(); Timer_A1_1_init(); _BIS_SR(CPUOFF); / Enter LPM0 进入低功耗模 式 0 SMCLK ON,ACLK ON 3,Timer_A 的捕获/比较寄存器 TAR 寄存器是 Timer_A 的 16 位的计数寄存器。TACCRx 是 Timer_A 的捕获/比较寄存器, 当为捕获模式时:当捕获发生时,把 TAR 的值装载到 TACCRx 中。当为比较模式时: TACCRx 中装的是要与 TAR 寄存器相比较的值。 4,捕获模式 捕获外部输入的信号的上升沿或下降沿或上升沿下降沿都捕捉,当捕捉发生时,把 TAR 的 值装载到 TACCRx 中,同时也可以进入中断,执行相应的操作。这样利用捕捉上升沿或下 降沿就可以计算外部输入信号的周期,得出频率。利用捕捉上升沿和下降沿可以得出输入 信号的高电平或低电平的持续时间。也可以算出占空比。下面是一个例子,是 Timer_A 捕 获初始化的程序: void timer_init() /使用 Timer1_A 时要特别注意各个寄存器的写法,因为 Timer0_A 的寄存器都简写了,所以在写 /Timer1_A 的寄存器时,要特别注意与 Timer0_A 的不同 P1SEL |= BIT2; /选择 P12 作为捕捉的输入端子 Timer0_A /TACCTL1 |=CM_3+SCS+CAP+CCIE; /上下沿都触发捕捉,用于测脉宽,同步模式、时能 中断 CCI1A TACCTL1 |=CM_1+SCS+CAP+CCIE; /上升沿触发捕捉,同步模式、时能中断 CCI1A TACTL |= TASSEL1+MC_2; /选择 SMCLK 时钟作为计数时钟源,不分频 增计数模 式不行,必须连续计数模式 P2SEL |= BIT1; /选择 P21 作为捕捉的输入端子 Timer1_A /TA1CCTL1 |=CM_3+SCS+CAP+CCIE; /上下沿都触发捕捉,用于测脉宽,同步模式、时 能中断 CCI1A TA1CCTL1 |=CM_1+SCS+CAP+CCIE; /上升沿触发捕捉,同步模式、时能中断 CCI1A TA1CTL |= TASSEL1+MC_2; /选择 SMCLK 时钟作为计数时钟源,不分频 增计数模 式不行,必须连续计数模式 相对应的中断函数如下: #pragma vector=TIMER0_A1_VECTOR /Timer0_A CC1 的中断向量 _interrupt void Timer_A(void) / CCI0A 使用的捕捉比较寄存器是 TA0CCR0,TA0CCR0 单独分配给一个 /中断向量 TIMER1_A0_VECTOR,所以进入中断后直接就是 Timer0_A CC0 产生的 中断,不用经过类似 /下面的方法判断中断源了 。 /Timer0_A CC1-4, TA0 公用一个中断向量 TIMER0_A1_VECTOR,所以进入了中断后还 要用下面 /的方法进行判断是哪一个中断源产生的中断 switch(TAIV) /如果是 Timer0_A CC1 产生的中断 case 2: flag=1; LPM1_EXIT; /退出低功耗模式 / _BIC_SR_IRQ(LPM1_bits); /_bic_SR_register_on_exit(LPM1_bits); break; case 4: break; case 10:break; #pragma vector=TIMER1_A1_VECTOR /Timer1_A CC1 的中断向量 _interrupt void Timer_A1(void) / P1OUT|=BIT0; /led 调试用的 / LPM1_EXIT; /退出低功耗模式 因为使用的是 CCI0A 使用的捕捉比较寄存器是 TA1CCR0,TA1CCR0 单独分配给一个 /中断向量 TIMER1_A0_VECTOR,所以进入中断后直接就是 Timer1_A CC0 产生的中断,不用经过类似 /下面注释掉的方法判断 。 /而 Timer1_A CC1-4, TA1 则公用一个中断向量 TIMER1_A1_VECTOR,所以进入了中断后还要用下面 /的方法进行判断是哪一个中断源产生的中断 switch(TA1IV) /如果是 Timer1_A CC1 产生的中断 case 2: flag=2; LPM1_EXIT; /退出低功耗模式 / _BIC_SR_IRQ(LPM1_bits); /_bic_SR_register_on_exit(LPM1_bits); break; case 4:break; case 10:break; /如果要测量更低频率的信号的话,可以在中断中判断溢出中断发生的次数,这样就可以 得到溢出的次数,从而可以测量更 /低频率的信号 5,Timer_A 的计数模式 计数模式有:增计数模式,连续计数模式和增减计数模式。具体的各个模式的详解,参见 用户指南。 6,定时器的定时中断 在使用定时器的定时中断时,要注意定时器计数模式的选择。在使用中断时,要注意中断 向量的使用和中断源的判断,下面就举一个例子,注释的也较详细: #include unsigned int t=0; void main(void) WDTCTL = WDTPW + WDTHOLD; / Stop WDT P1DIR |= 0x01; / P1.0 output CCTL0 = CCIE; / CCTLx 是捕获/比较控制寄存器 interrupt enabled CCIE=0x0010 时能定时器 A 中断 CCR0 = 50000; /捕获/比较寄存器 设置计数器 CCR0 的初值 16 位寄存器,最大 值为 65535 /默认 SMCLK 使用的是 DCO,默认的 DCO 大约为 800KHz,而 CCR0=50000,所以中断产生的频率大约为 16Hz TACTL = TASSEL_2 + MC_2; / SMCLK, contmode 连续计数模式从 0 计到 0FFFFh /TACTL = TASSEL_2 + MC_1; / SMCLK, upmode 增计数模式从 0 计到 CCR0 _BIS_SR(LPM0_bits + GIE); / Enter LPM0 w/ interrupt 进入低 功耗模式 0,允许中断 / Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR _interrupt void Timer_A (void) /CCIFG 中断被响应后,该标志位自动清零 /P1OUT = 0x01; / Toggle P1.0 t+; if(t=5) P1OUT = BIT0; / Toggle P1.0 t=0; CCR0 += 50000; / Add Offset to CCR0 增加 CCR0 偏 移 /定时器总是从 0 开始往上计数,一直到计满再从 0 开始,在连续计数模式下,当定时 器的值等于 CCR0 时,产生中断 /在中断中对 CCR0 增加 50000,这样的话定时器从当前值到下一时刻再次等于 CCR0 时的间隔为 50000,恒定 /这样产生中断的时间间隔就相等了 /所以在连续计数模式下,要想使中断的时间间隔一定,就要有 CCR0 += n;这句话 /在中断中 CCR0 不需要从新赋值, 区别于 51 中断的使用注意情况:还是把举个例子吧: #include void main(void) WDTCTL = WDTPW + WDTHOLD; / Stop WDT P1DIR |= 0x01; / P1.0 output TACTL = TASSEL_2 + MC_2 + TAIE; / SMCLK, contmode, interrupt TAIE 允许定时器溢出中断 _BIS_SR(LPM0_bits + GIE); / Enter LPM0 w/ interrupt GIE 允 许中断 / Timer_A3 Interrupt Vector (TA0IV) handler #pragma vector=TIMER0_A1_VECTOR _interrupt void Timer_A(void) switch( TA0IV ) /TAIV 中断向量寄存器 用于 case 2: break; / CCR1 not used 捕获/比较器 1 case 4: break; / CCR2 not used 捕获/比较器 2 case 10: P1OUT = 0x01; / overflow 定时器溢出 break; 7,注意:定时器 Timer0_A 的时钟可以选择为外接时钟输入 TACLK(P10 ),这样当外 接一个信号时,定时器 Timer0_A 就相当于一个计数器使用。这样就可以用 Timer0_A 接外 接信号,Timer1_A 接标准的时钟如 32768Hz 的晶振,就可以实现等精度测频了。其实 Timer1_A 的时钟也可以外接的,但是在 g2553 中没有这个外接管脚(P37),所以就只能 选择正常的时钟了。 Timer0_A 的外接时钟输入 TACLK(P10 )的设置如下:下面是我实现等精度测频时,两个 定时器的初始化程序: void timer0_init() TACTL |= TASSEL_0+MC_2+TACLR; /选择 TACLK 时钟作为计数时钟源,不分频 必须 连续计数模式 P1SEL |= BIT0; /P10 为 Timer0_A 的时钟 TACLK 输入,接外部待测信号,这样 Timer0_A 就当作计数器用 /Timer1_A 采用 ACLK 作为时钟源计数,这样 ACLK 就相当于是标准信号,这样两个定 时器相当于都工作在计数器方式, /ACLK 32768Hz 作为标准信号,这样可以实现等精度测频 void timer1_init() TA1CCTL0 = CCIE; TA1CCR0 = 32768; /1s 定时 TA1CTL |= TASSEL_1+MC_2+TACLR; /选择 ACLK 时钟作为计数时钟源,不分频 必须 连续计数模式 8,用定时器和比较器可以实现 DAC 使用定时器也可以实现串口通信 (四),ADC10 1,ADC10 是十位的 AD,在 g2553 上有 A0A7 八个可以外接的 AD 通道,A10 接到片上的温 度传感器上,其他的通道都接在内部的 V或 GND 上。因为是为的所以计算公 式如下: 2 ,ADC 参考电压的选择:ADC 的参考电压可以为: 由 ADC 控制寄存器 0 ADC10CTL0 控制。但是要提高 ADC 的精度的话,尽量不要用内部的参 考电压,最好外接一个比较稳定的电压作为参考电压,因为内部的产生的参考电压不是特 别稳定或精度不是特别的高。例如我在使用时遇到的情况如下: Vref 设为 2.5V 但实际的值大概为 2.475V, 选择 VCC VSS 作为参考,用电压表测得大 概为 3.58V 还是不小的偏差的。 另外,在有可能的情况下,尽量采用较大的 VR+和 VR-,以减小纹波对采样结果的影响。 3,ADC10 的采样方式有:单通道单次采样,单通道多次采样,多通道单次采样,多通 道多次采样。 4,DTC:因为 ADC10 只有一个采样结果存储寄存器 ADC10MEM,所以除了在单通道单次采样 的模式下,其他的三个模式都必须使用 DCT,否则转换结果会不停地被新的结果给覆盖。 DTC 是转换结果传送控制,也就是转换结果可以不用 CPU 的干预,就可以自动地存储在指 定的存储空间内。使用这种方式转换速度快,访问方便,适用于高速采样模式中。DTC 的 使用可以从下面的例子中很容易看明白: #include #include “ser_12864.h“ uchar s1=“DTC:“; uchar s2=“2_cha_2_time_DTC“; void ADC_init() ADC10CTL1 = CONSEQ_3 + INCH_1; / 2 通道多次转换, 最大转换通道为 A1 ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE; / ADC10ON, interrupt enabl 参考电压选默认值 VCC 和 VSS /采样保持时间为 16 x ADC10CLKs,ADC 内核开,中断使能 MSC 多次转换选择开 /如果 MSC 置位,则第一次开始转换时需要触发源触发一次,以后的转换会自动进行 中断使能 /使用 DTC 时,当一个块传送结束,产生中断 /数据传送控制寄存器 0 ADC10DTC0 设置为默认模式:单传送块模式,单块传送完停止 ADC10DTC1 = 0x04; /数据传送控制寄存器 1 4 conversions 定义在每块的传送数目 一共采样 4 次 所以单块传送 4 次 /以后就停止了传送 因为是两通道的,所以是每个通道采样数据传送 2 次 ADC10AE0 |= BIT0+BIT1; / P1.0 P1.1 ADC option select 使能模拟输入脚 A0 A1 /不知道为什么,当 P10 P11 都悬空时,采样值不同,用电压表测得悬空电压不同, 但是当都接上采样源的时候, /采样是相同的 void main(void) uint adc_sample8=0; /存储 ADC 序列采样结果 WDTCTL = WDTPW+WDTHOLD; BCSCTL1 = CALBC1_12MHZ; /设定 cpu 时钟 DCO 频率为 12MHz DCOCTL = CALDCO_12MHZ; P2DIR |=BIT3+BIT4; /液晶的两条线 init_lcd(); ADC_init(); wr_string(0,0,s1); wr_string(0,3,s2); for (;) ADC10CTL0 /ADC 不使能 其实这句话可以放在紧接着 CPU 唤醒之后的, 因为 CPU 唤醒了,说明我们想要的 /转换数据传送完成了,如果 ADC 继续转换,那么转换结果也不再传输,是无用的。 所以紧接着放在 CPU 唤醒之后 /计时关闭 ADC,有利于降低功耗 while (ADC10CTL1 / Wait if ADC10 core is active 等待忙 ADC10SA = (unsigned int)adc_sample; /数据传送开始地址寄存器 设置 DTC 的开始地址 Data buffer start /设置数据开始传送的地址为数组 adc_sample的首地址,因为寄存器 ADC10SA 和转换结果都是 16 位的,所以要把 /地址强制转换为 16 位的 int 或 unsigned int /应该也可以用指针直接访问 DTC 的存储区,还没试过 /例如:前面定义了单块传送 4 次数据,所以每次传送完成了一个块,也就是 4 次,就会把中断标志位置位,产生中断 /因为上面设置的地址为数组 adc_sample的首地址,所以每次转换的结果就会 传送到该数组的前 4 位上,所以如果 /一切正常的话,数组里应该是前 4 位为转换的结果,后 4 位为初始值 0 通过 下面的显示,验证转换是正确的 /一次触发首先对 A1、A0 采样,放入 a0和 a1中,再对 A1、A0 采样,放入 a2和 a3中。如此循环下去。 /验证得知,当多通道采样时,先采高的通道,再采低的通道。如上面每次采样 时,先采 A1 再 A0 /因为一共采样传送 4 次,所以数组的后 4 位为初始值 0 ADC10CTL0 |= ENC + ADC10SC; / Sampling and conversion start ADC 使能, 开始转换 ADC10SC 为采样触发源 /不需要 cpu 的干预,DTC 就可以把采样结果存储到指定的存储区中 _bis_SR_register(CPUOFF + GIE); / LPM0, ADC10_ISR will force exit 如果转换结果传送完成, /就会进入中断,CPU 唤醒 继续往下运行 wr_int(2,0,adc_sample0); /显示转换结果 A1 wr_int(6,0,adc_sample1); /A0 wr_int(0,1,adc_sample2); /A1 wr_int(3,1,adc_sample3); /A0 wr_int(6,1,adc_sample4); wr_int(0,2,adc_sample5); wr_int(3,2,adc_sample6); wr_int(6,2,adc_sample7); / ADC10 interrupt service routine #pragma vector=ADC10_VECTOR _interrupt void ADC10_ISR(void) /中断响应以后,中断标志位自动清零 _bic_SR_register_on_exit(CPUOFF); / Clear CPUOFF bit from 0(SR) 上面的例子是把存储结果存储在了 uint 型的数组中。也可以用指针直接指定要存放的地址, 然后再用指针进行访问(理论上可以,但还没有试过)。也可以把存储结果直接存放在一 个 16 位的寄存器中,如: ADC10SA = (unsigned int) / Data transfer location 把转换结果存 储在 TACCR1 所在的 /位置处,就相当于存储在 TACCR1 中 因为 ADC 转换结果和寄存器 TACCR1 都是 16 位 的,所以要把地址强制转换为 16 位的 /int 或 unsigned int 型 5,ADC 采样注意事项:用片上的 ADC10 进行采样,如果外部分压电路的电阻过大(比如 几 K 以上),AD 引脚会把电压拉高,使采样结果发生很大的偏差。应换成小电阻(几十 几百欧),如果要求更精确的话,要加运放进行电压跟随。 6,AD 采样交流信号: 一般是 50Hz,100Hz,1000Hz。方法是在交流信号的一个周期内采样多次(如 40 次,30 次 等),然后利用公式可以求出交流信号的有效值,平均值等。 7,片上温度传感器 ADC 的 A10 通道接片上的温度传感器,MSP430 内嵌的温度传感器实际上就是一个输出电压 随环境温度而变化的温度二极管。 当使用片上温度传感器时,采样周期必须大于 30us 片上温度传感器的偏移很大,所以 精确测量需要 进行校准。选择片上温度传感器 INCH_10,ADC 其他的设置都和外部通道的设置相同,包括 参考电压源的选择和转换存储的选择 选择了片上温度传感器,会自动地打开片上参考电压源发生器作为温度传感器的电压源, 但是这并不会时能 VREF+输出,也不会 影响 AD 转换参考源的选择,转换参考源的选择和其他通道的选择相同 公式为:VTEMP=0.00355(TEMPC)+0.986 片上温度传感器的校准,可以参见我的温度传感器校准程序,也可以参考其他的论文。下 面只给出程序的一部分: void ADC_init() ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; / ADC10ON, interrupt enabled 参考 电压选默认值 VCC 和 VSS /采样保持时间为 16 x ADC10CLKs,ADC 开,中断使能 ADC10CTL1 = INCH_10; / ADC 输入通道选择 A10,为内部的温度传感器 /其他是默认,采样触发输入源选择为 ADC10SC,采样输入信号不翻转,转换时钟选择内 部时钟源:ADC10OSC,3.76.3MHz /不分频,单通道单次转换 /ADC10AE0 |= 0x02; / PA.1 ADC option select 使能模拟 输入脚 A1 /P1DIR |= 0x01; / Set P1.0 to output direction /所以是 P11 为 ADC 输入脚,P10 控制 led (五),通用串行通信接口(USCI) 1,USCI_A:支持 UART, IrDA, SPI USCI_B:支持 I2C, SPI 2,UART 这个模块没什么好说的,和其他的一写处理器如 S12,ARM 等差不多。只要 设置好几个控制寄存器,波特率,写几个收发函数就可以了。下面就给出 msp430g2553 于 PC 用 UART 通信的基本程序: #include “msp430g2553.h“ unsigned char rev; char *string1=“Helloworld!“; char string2=“Get it!n“; /n 是换行符 void putchar(unsigned char c) /发送字符函数 while (!(IFG2 / USCI_A0 TX buffer ready? 等待 TX buffer 为空 UCA0TXBUF = c; / TX - RXed character 发送字符 c void putstr(char *s) /发送字符串函数 IE2 /发送时先关闭接收中断,不接收 while(*s)!=0) /如果没有发完,就继续循环发送 putchar(*s); / putchar(n); /发送换行符 s+; IE2 |= UCA0RXIE; /发送完了打开接收中断 void main(void) WDTCTL = WDTPW + WDTHOLD; / Stop WDT P1DIR=BIT0; BCSCTL1 = CALBC1_1MHZ; / Set DCO 为 1MHz DCOCTL = CALDCO_1MHZ; P1SEL = BIT1 + BIT2 ; / P1.1 = RXD, P1.2=TXD P1SEL2 = BIT1 + BIT2; /第二外围模式选择 / UCA0CTL1 |= UCSSEL_2; / SMCLK 其他默认:软件复位使能 USCI 逻辑保 持在复位状态,用于设置串口 /UCA0CTL0 全部为默认状态:无奇偶校验,LSB first,8bit_data,一位停止位,UART 模 式,异步模式 / UCA0BR0 = 8; / SMCLK 1MHz 115200 8 / UCA0BR1 = 0; / 1MHz 115200 / UCA0MCTL = UCBRS2 + UCBRS0; / Modulation UCBRSx = 5 /下面是选择 ACLK,波特率设置为固定的 UCA0CTL1 |= UCSSEL_1; /ACLK UCA0BR0 = 3; / ACLK 32768Hz 9600 32768Hz/9600 = 3.41 UCA0BR1 = 0; / 32768Hz 9600 UCA0MCTL = UCBRS1 + UCBRS0; / Modulation UCBRSx = 3 UCA0CTL1 / *Initialize USCI state machine* 初始化释放,可以操作 IE2 |= UCA0RXIE; / Enable USCI_A0 RX interrupt 接 收中断使能 _bis_SR_register(LPM0_bits + GIE); / Enter LPM0, interrupts enabled / Echo back RXed character, confirm TX buffer is ready first #pragma vector=USCIAB0RX_VECTOR _interrupt void USCI0RX_ISR(void) while (!(IFG2 / USCI_A0 TX buffer ready? 等待 TX buffer 为空 UCA0TXBUF = UCA0RXBUF; / TX - RXed character 发送接收到 是数据 rev=UCA0RXBUF; if(rev putstr(string1); putstr(string2); else P1OUT 注意:关于波特率的设置这一块还没有看懂,但上面的例子总的设置是对的 值得说明的是:可以用定时器来实现串口通信功能,例子还没有看。 3,对于 SPI 和 I2C,有时有可能会用于 g2553 和其他的一些芯片、设备的通信用,还 没没仔细看。 (六),比较器 A Comparator_A+ 1,是一个模拟电压比较器,主要功能是指出两个输入电压 CA0 和 CA1 的大小关系,然后 由输出信号 CAOUT 输出。 2,输出:如果正端输入电压大于负端输入电压,输入为 1。如果负端输入电压大于正端 输入电压,输出为 0; 3,最终输出信号的上升沿或下降沿可以设置为具有中断能力,中断响应后,硬件会自动 清除中断标志位 CAIFG,也可以被软件清除。 4,Comparator_A+支持精密的斜坡 AD 转换,供电电压检测和监视外部模拟信号。 5,比较器的其中一路可以接参考电压,有 0.25VCC, 0.5VCC, 三极管的阀值电压 0.55V 也可以两路信号都接外部的模拟信号。 6,更详细的内容,参见用户只能,下面的例子是简单的用比较器 A 比较两个输入模拟电 压的高低,有 CAOUT 输出: /主要功能是比较两个输入信号的大小关系 #include void delay(void); / Software delay void main (void) WDTCTL = WDTPW + WDTHOLD; / Stop WDT CACTL2 = P2CA4; / CA1/P1.1 = +comp 正输入端信号选择 CA1,负输入端信号不连 接外部输入信号 /其他位的设置为默认:比较器输出不滤波 , CAOUT 为比较器的输出结果 CCTL0 = CCIE; / CCR0 interrupt enabled TACTL = TASSEL_2 + ID_3 + MC_2; / SMCLK/8, cont-mode _EINT(); / enable interrupts while (1) / Loop /比较器 A 控制寄存器 1 CACTL1 采用的是默认设置:参考电压源 VCAREF 加到比较器的正 输入端,内部参考源关,比较器关, /中断不使能 CACTL1 = 0x00; / No reference voltage _BIS_SR(LPM0_bits); / Enter LPM0 CACTL1 = CAREF0 + CAON; / 参考源为 0.25*Vcc, Comp. on _BIS_SR(LPM0_bits); / Enter LPM0 CACTL1 = CAREF1 + CAON; / 参考源为 0.5*Vcc, Comp. on _BIS_SR(LPM0_bits); / Enter LPM0 CACTL1 = CAREF1 + CAREF0 + CAON; /参考源为三极管的阀值电压 0.55V, Comp. on _BIS_SR(LPM0_bits); / Enter LPM0 / Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR _interrupt void Timer_A (void) _BIC_SR_IRQ(LPM0_bit
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 防虫植物墙施工方案
- 2025年抗菌药物培训试卷(+答案)
- 2025年叉车司机考试车辆维修保养知识考试题库及答案
- 图书馆馆藏建设课件
- 2025年光伏电站土地流转与农村土地流转利益分配报告
- 零冷水燃热改造工程方案(3篇)
- 2025年教育信息化基础设施建设与教育信息化政策研究报告
- 工程施工方案预算会议(3篇)
- 2025年新能源行业环保政策对产业发展的影响报告
- 消毒清洁质量试题及答案
- 收银技能理论考试题及答案
- 1.1 常见的植物(教学课件)科学青岛版二年级上册(新教材)
- 2025污水处理综合考试题及答案
- 2025年学习二十届全会精神知识竞赛题库及答案
- 2025福建漳州闽投华阳发电有限公司招聘52人备考试题及答案解析
- 初一启新程扬帆再出发-2025-2026学年上学期七年级(初一)开学第一课主题班会课件
- 寿险调查培训课件下载
- 中国法制史试题题库(附答案)
- Z20名校联盟(浙江省名校新高考研究联盟)2026届高三第一次联考 语文试卷(含答案详解)
- 企业科技创新管理办法
- GB/T 37507-2025项目、项目群和项目组合管理项目管理指南
评论
0/150
提交评论