用按键控制LED灯的亮灭

更新时间:2024-03-17 10:23:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

用按键控制LED灯的亮灭,当按键按下时,LED灯亮,当按键松开时,LED灯灭。 #include%unsigned char flag; void main(void) {

WDTCTL = WDTPW+WDTHOLD; // Stop WDT P4DIR &=~(BIT2);

P4DIR |= BIT4+BIT5+BIT6; // P4.4,P4.5,P4.6 set as output P4OUT &=~(BIT4+BIT5+BIT6); // set led off P2IE |= BIT6; // enable P2.6 interrupt P2IFG &= ~(BIT6); // clean interrupt flag __enable_interrupt(); // enable interrupt while(1)

{ if((P4IN & 0x04)==0) { P2IFG |= BIT6;} else

{P2IFG &=~BIT6;}}

} // PORT2 interrupt service routine #pragma vector=PORT2_VECTOR __interrupt void port_2(void)

{P4OUT ^=(BIT4+BIT5+BIT6); // set led on

P2IFG &=~BIT6; // clean interrupt flag}

用按键控制LED灯的亮灭,当按键按下时,LED灯亮,当按键松开时,LED灯灭。(查询) #include\void main(void)

{WDTCTL = WDTPW+WDTHOLD; // Stop WDT //setting direction P4DIR &= ~(BIT2); //setting IO for input

P4DIR |= BIT4+BIT5+BIT6; // P4.4,P4.5,P4.6 set as output while (1)

{if ((P4IN & 0x04) == 0) //If key is pressed {P4OUT |= BIT4+BIT5+BIT6; //led on} else{P4OUT &=~(BIT4+BIT5+BIT6); // led off}}}

将ACLK配置为VLOCLK(约为10K),并将ACLK通过P1.0口输出 #include void main(void)

{WDTCTL = WDTPW + WDTHOLD; //关看门狗

UCSCTL4 |= SELA_1; //将ACLK时钟源配置为VLO; P1DIR |= BIT0;

P1SEL |= BIT0; //将ACLK通过P1.0输出

__bis_SR_register(LPM3_bits);//进入LPM3,SMCLK和MCLK停止,ACLK活动} 设ACLK = XT1 = 32768Hz,并通过P1.0输出。 #include void main(void)

{WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= BIT0; // ACLK set out to pin P1SEL |= BIT0;

P5SEL |= BIT4+BIT5; // Select XT1

while(BAKCTL & LOCKIO) // Unlock XT1 pins for operation BAKCTL &= ~(LOCKIO);

UCSCTL6 &= ~(XT1OFF); // XT1 On

UCSCTL6 |= XCAP_3; // Internal load cap

// Loop until XT1 fault flag is cleared do

{UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);

SFRIFG1 &= ~OFIFG; // Clear fault flags

}while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~(XT1DRIVE_3); // reduce drive strength

UCSCTL4 |= SELA_0; // ACLK = LFTX1 (by default) __bis_SR_register(LPM3_bits); // Enter LPM3 }

设ACLK = XT1 = 32768Hz,令SMCLK = XT2CLK,MCLK = DCO(默认) = 32 x ACLK = 1048576Hz,ACLK和SMCLK分别通过P1.0和P3.4输出。 #include void main(void) {

WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT0; // ACLK set out to pins P1SEL |= BIT0;

P3DIR |= BIT4; // SMCLK set out to pins P3SEL |= BIT4;

while(BAKCTL & LOCKIO) // Unlock XT1 pins for operation BAKCTL &= ~(LOCKIO);

P7SEL |= BIT2+BIT3; // Port select XT2 UCSCTL6 &= ~XT2OFF; // Set XT2 On UCSCTL6 &= ~(XT1OFF); // XT1 On

UCSCTL6 |= XCAP_3; // Internal load cap do

{UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);

SFRIFG1 &= ~OFIFG; // Clear fault flags

}while (SFRIFG1&OFIFG); // Test oscillator fault flag

UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to // expected frequency

UCSCTL4 |= SELA_0 + SELS_5; // Select SMCLK, ACLK source andDCO source

while(1); // Loop in place }

设ACLK = TACLK = LFXT1 = 32768, MCLK = SMCLK = DCOCLK = 32×ACLK = 1.048576Mhz,利用Timer_A输出周期为512 /32768 = 15.625ms、占空比分别为75%和25%的PWM矩形波: #include void main(void)

{WDTCTL = WDTPW + WDTHOLD; // Stop WDT while(BAKCTL & LOCKIO) BAKCTL &= ~(LOCKIO); // Unlock XT1 pins for operation UCSCTL6 &= ~(XT1OFF); // XT1 On

UCSCTL6 |= XCAP_3; // Internal load cap // Loop until XT1 fault flag is cleared do

{UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);

SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag

P1DIR |= BIT2+BIT3; // P1.2 and P1.3 output P1SEL |= BIT2+BIT3; // P1.2 and P1.3 options select TA0CCR0 = 512-1; // PWM Period

TA0CCTL1 = OUTMOD_7; // CCR1 reset/set

TA0CCR1 = 384; // CCR1 PWM duty cycle TA0CCTL2 = OUTMOD_7; // CCR2 reset/set

TA0CCR2 = 128; // CCR2 PWM duty cycle

TA0CTL = TASSEL_1 + MC_1 + TACLR; // ACLK, up mode, clear TAR __bis_SR_register(LPM3_bits); // Enter LPM3 __no_operation(); // For debugger }

由程序知:P1.2—> TA0CCR1 - 75% PWM,P1.3—> TA0CCR2 - 25% PWM。周期15.625ms

利用定时器实现开发板上的LED灯以1Hz的频率闪烁 #include void main(void)

{ WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗

P4DIR |= BIT4 + BIT5 + BIT6; // P4.4、P4.5、P4.6设为输出 TA0CCTL0 = CCIE; // CCR0中断使能 TA0CCR0 = 16384;

TA0CTL = TASSEL_1 + MC_1 + TACLR; // ACLK, 增计数模式, 清除TAR计数器 __bis_SR_register(LPM0_bits + GIE); // 进入LPM0,使能中断 }// TA0中断服务程序

#pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void)

{P4OUT ^= (BIT4 + BIT5 + BIT6);// LED灯取反;} #pragma vector=TIMER0_A1_VECTOR __interrupt void TIMER0_A1_ISR(void) { switch(__even_in_range(TA0IV,14)) { case 0: break; // No interrupt case 2: break; // CCR1中断 case 4: break; // CCR2中断 case 6: break; // CCR3中断 case 8: break; // CCR4中断 case 10: break; // reserved case 12: break; // reserved case 14: // 溢出中断 P4OUT ^= BIT4;break; default: break; } }

将长字0x12345678写入InfoD中,地址为0x1800,当写完后P4.5绿色指示灯闪烁。 #include #include \

uint32_t *FLASH_ptrD = (uint32_t *) 0x1800; // 初始化FLASH信息段D(Info D)指针,指向Info D首地址 void main(void)

{ uint32_t value = 0x12345678;

WDTCTL = WDTPW+WDTHOLD; // 关闭看门狗定时器 P4DIR |= BIT5; __disable_interrupt(); // 擦除前,关闭全局中断 while(FCTL3 & BUSY); // 判断是否处于忙碌状态 FCTL3 = FWKEY; // 清除LOCK标志 FCTL1 = FWKEY + ERASE; // 置位ERASE位,选择段擦除 *FLASH_ptrD = 0; // 空写操作,地址可以为段范围任意值 FCTL1 = FWKEY +BLKWRT; // 写允许,写长字 *FLASH_ptrD = value; // 写FLASH while(FCTL3 & BUSY);// 判断是否处于忙碌状态 __enable_interrupt(); FCTL1 = FWKEY; // 清除WRT位 FCTL3 = FWKEY + LOCK; // 置位LOCK标志 __no_operation(); // 此处设置断点,便于调试 while(1) {P4OUT ^= BIT5;// 烧写完毕,闪烁指示灯 __delay_cycles(1000000);} }

将InfoC中的数据拷贝至InfoD中,当拷贝完成后P4.5绿色指示灯闪烁 #include #include \void copy_C2D(void); void main(void)

{ WDTCTL = WDTPW+WDTHOLD; // 关闭看门狗定时器 P4DIR |= BIT5; copy_C2D(); while(1) {P4OUT ^= BIT5;// 烧写完毕,闪烁指示灯 __delay_cycles(1000000);} }

void copy_C2D(void) { unsigned int i; char *Flash_ptrC; char *Flash_ptrD;

Flash_ptrC = (char *) 0x1880; // 初始化信息段C指针 Flash_ptrD = (char *) 0x1800; // 初始化信息段D指针 FCTL3 = FWKEY; // 清除锁定控制位 FCTL1 = FWKEY+ERASE; // 段擦除

__disable_interrupt(); // Flash操作期间不允许中断,否则将导致不可预计的错误 *Flash_ptrD = 0; // 空写,启动擦除

while(FCTL3 & BUSY); // 等待擦除操作完成

FCTL1 = FWKEY+WRT; // 采用字节/字写入模式 for (i = 0; i < 128; i++)

{*Flash_ptrD++ = *Flash_ptrC++; // 将信息段C的内容复制到信息段D内} while(FCTL3 & BUSY); // 等待写除操作完成

__enable_interrupt(); // 启动全局中断 FCTL1 = FWKEY; // Flash退出写模式

FCTL3 = FWKEY+LOCK; // 恢复Flash锁定位,保护数据 }

往RAM中写入递增的数据,首地址为0x4400,然后关闭开关控制位,使之失效 #include #include \

#define NumToWrite 8 volatile int i; void main(void)

{ unsigned long value[NumToWrite];

unsigned char *RAM_ptr = (uint8_t *) 0x4400; WDTCTL = WDTPW + WDTHOLD; P4DIR |= BIT5;

// 地址自动加1,向指针指向的RAM单元写入递增的i数值,观察Memory Browser for(i=0; i

// 地址自动加1,读出RAM中之前写入的递增数值,观察Memory Browser for(i=0; i

__no_operation(); //此处用来测试

// 关闭寄存器 RCCTL0 位RCRS2OFF,则写无效,清除前面的数 RCCTL0 = RCKEY + RCRS2OFF; RAM_ptr = (uint8_t *) 0x4400;

// 观察Memory Browser,发现RAM中的数据得到保护,此次写无效 for(i = NumToWrite-1; i>=0; i--) *RAM_ptr++ = i; __no_operation(); //此处用来测试 while(1) { P4OUT ^= BIT5;// 烧写完毕,闪烁指示灯 __delay_cycles(1000000); } }

数码管动态显示数字0—5 void Init_lcd(void) { LCDBCTL0 =LCDDIV0 + LCDPRE0 + LCD4MUX ;//1分频,时钟源ACLK,4MUX驱动 LCDBPCTL0 = LCDS0 + LCDS1 + LCDS2 + LCDS3 + LCDS4 + LCDS5 + LCDS6+ LCDS7 + LCDS8+ LCDS9 + LCDS10 + LCDS11 ; P5SEL |= BIT3 + BIT4 + BIT5;} void Backlight_Enable(void) { P8DIR |= BIT0; P8OUT |= BIT0;}

void LCD_Clear(void)//清屏 {unsigned char index;

for (index=0; index<12; index++) {LCDMEM[index] = 0;} }

void LcdGo(unsigned char Dot) { if(Dot==1)

{ LCDBCTL0 |= LCDON;} else if(Dot==0) {//关闭液晶显示

LCDBCTL0 &= ~LCDON;}} void main(void) { ……

Init_lcd(); // LCD初始化 Backlight_Enable(); // 打开背光

LcdGo(1); // 打开液晶模块 LCD_Clear(); // 清屏 while(1)

{ for (i=0; i<6; i++) // Display \{for(j=0;j<6;j++)

{LCDMEM[j] = char_gen[i];} delay_ms(1000);}}}

比较器输入通道CB6接外部模拟信号,并引至比较器“+”输入端。内部参考电压发生器利用共享电压源产生1.5V参考电压,并引至比较器“-”输入端。利用比较器中断,当CB6输入模拟信号电压高于1.5V时,拉高P4.4引脚;当CB6输入模拟信号电压低于1.5V时,拉低P4.4引脚。调节电位器RP1,观察L6灯的状态变化 #include void main(void)

{ WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗

P4DIR |= BIT4; // 将P4.4设为输出 CBCTL0 |= CBIPEN + CBIPSEL_0; // 启用CB0,并将其引至正输入端 CBCTL1 |= CBPWRMD_1; // 正常电源模式

CBCTL2 |= CBRSEL; // 内部参考电压VREF引至负输入端

CBCTL2 |= CBRS_3+CBREFL_1; // 梯形电阻电路禁用,产生1.5V内部共享电压

CBCTL3 |= BIT6; // 启用P6.6/CB6比较器功能 __delay_cycles(75); // 延迟以待参考电压稳定 CBINT &= ~(CBIFG + CBIIFG); // 清除比较器中断标志位

CBINT |= CBIE; // 使能比较器CBIFG上升沿中断(CBIES=0) CBCTL1 |= CBON; // 打开比较器B __bis_SR_register(LPM4_bits+GIE);// 进入LPM4 }

// Comp_B中断服务程序- 反转P4.4口状态 #pragma vector=COMP_B_VECTOR __interrupt void Comp_B_ISR (void)

{CBCTL1 ^= CBIES; // 切换中断触发方式 CBINT &= ~CBIFG; // 清除中断标志位 P4OUT ^= BIT4; // 反转P4.4口状态 }

调节电位器,观察实验板上的TFT LCD显示,随着电位器的转动,LCD显示输入模拟电压的最转换结果NADC也随着相应的改变。输入模拟电压的最转换结果满足公式:NADC=4096×(Vin – VR-)/(VR+ - VR-) void main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer Init_TS3A5017DR(); // Configure TS3A5017DR IN1 and IN2 Init_lcd(); // lcd初始化 LcdGo(1); // 打开液晶模块 LCD_Clear(); //清屏 Backlight_Enable(); P6SEL |= BIT6; // Enable A/D channel ADC12CTL0 = ADC12ON+ADC12SHT0_15+ADC12MSC ; ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2 + ADC12SSEL_1; ADC12MCTL0 |= ADC12INCH_6; //change ADC12IE = ADC12IE0; // Enable ADC12IFG.0 ADC12CTL0 |= ADC12ENC; // Enable conversions ADC12CTL0 |= ADC12SC; // Start conversion _EINT(); // Enable all interrupt _BIS_SR(LPM4_bits + GIE); // Enter LPM4, Enable interrupts __no_operation(); // For debugger }

#pragma vector=ADC12_VECTOR __interrupt void ADC12ISR (void)

{results[index++] = ADC12MEM0; // Move results if(index == NumOfResult) { uint16_t i;

average = 0; for(i = 0; i < NumOfResult; i++) {average += results[i]; results[i] = 0;} average >>= 3; //除以8 Conversion(average , 10, con); Trans_val(average , 10, trans_v); index = 0; LCDMEM[5] = char_gen[con[3]-48]; LCDMEM[4] = char_gen[con[2]-48]; LCDMEM[3] = char_gen[con[1]-48]; LCDMEM[2] = char_gen[con[0]-48]; for(i=0;i < NumOfResult;i++) {con[i] = 0 ; trans_v[i] = 0;}}} 用DAC12输出1V模拟电压 #include void main(void)

{WDTCTL = WDTPW + WDTHOLD;

DAC12_1CTL0 = DAC12IR + DAC12SREF_1 + DAC12AMP_5 + DAC12CALON + DAC12OPS + DAC12ENC;//满程输出电压是参考电压的1倍,参考电压选择VCC,输入输出中速度/电流,进行校验,输出选择P7.7,开始转换 DAC12_1DAT = 0X4D9;//4096÷3.3=1241=0X4D9 __bis_SR_register(LPM4_bits); }

用DAC12输出正弦波信号 #include #include #define PI 3.1415926 int sin_table[360]; int *sin_data_pr; double i=0; int j;

void main(void)

{WDTCTL = WDT_MDLY_0_064; // WDT 61us定时

SFRIE1 = WDTIE; // 打开 WDT中断 for(j=0;j<360;j++)

{i+=PI/180; // 步长PI/180

sin_table[j]=(int)((sin(i)+1)*2048);// 每个i对应的sin值换算为12位分辨时的数据写入数组} sin_data_pr=&sin_table[0]; //指向数组的指针

DAC12_1CTL0 = DAC12IR + DAC12SREF_0 + DAC12AMP_5 + DAC12CALON +

DAC12OPS + DAC12ENC;// VREF+作为参考电压,初始化偏移量校正,端口选择DAC输出,DAC12使能 while(1)

{__bis_SR_register(CPUOFF + GIE); // 进入LPM0

DAC12_1DAT=*sin_data_pr++; //将计算出的sin_table的值写入DAC12_0DAT if (sin_data_pr >= &sin_table[360]) //循环输出正弦波 {sin_data_pr = &sin_table[0];}

DAC12_1DAT &= 0xFFF; // 数据保持 __no_operation();} }

#pragma vector = WDT_VECTOR __interrupt void watchdog_timer (void) {__bic_SR_register_on_exit(CPUOFF);}

用串口调试助手通过串口向实验板发送数据,收到同样的数据反馈 #include void main(void)

{ WDTCTL = WDTPW + WDTHOLD; // Stop WDT P7DIR |= BIT4 + BIT5;//方向设置为输出 P7OUT &=~ BIT5; P7OUT |= BIT4;

P8SEL |= BIT2 + BIT3;

UCA1CTL1 |= UCSWRST; // 复位寄存器设置 UCA1CTL1 |= UCSSEL_1; // CLK = ACLK UCA1BR0 = 0x03; // 波特率设置为9600 UCA1BR1 = 0x00; //

UCA1MCTL = UCBRS_3+UCBRF_0; // 调制器设置 UCBRSx=3, UCBRFx=0 UCA1CTL1 &= ~UCSWRST; // 完成USCI_A0初始化配置 UCA1IE |= UCRXIE; // 使能USCI_A0 接收中断

__bis_SR_register(GIE); // 进入LPM0,并使能全局中断 }

#pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) {switch(__even_in_range(UCA1IV,4))

{ case 0:break; // 中断向量0 - 无中断 case 2: // 中断向量 2 - 接收中断

while (!(UCA1IFG&UCTXIFG)); // USCI_A0 是否发送完成

UCA1TXBUF = UCA1RXBUF; // 将接收缓冲器的字符传送给发送缓冲器,发送给PC,在串口调试助手中回显

case 4:break; // 中断向量 4 - 发送中断 default: break; } }

本文来源:https://www.bwwdw.com/article/5ph8.html

Top