MSP430 按键程序范例(附原理图)
MSP430触摸按键程序

//***************************************************************************** *// MSP430F20x3 Demo - Capacitive Touch Sensing 4-Key Demo// Description: This demo implements a 4-key capacitive touch detection.// The LED indicates the key which is pressed through four different levels of // brightness. Key#1 -> 100%, Key#2 -> 75%, Key#3 -> 50%, Key#4 -> 25%.// A calibration process is implemented to accommodate for possible variations // in VLO frequency. Normal operating mode is LPM3.//// ACLK = VLO ~ 12kHz, MCLK = Calibrated 8MHz / 4 = 2MHz,// SMCLK = Calibrated 8MHz//// MSP430F20x3// -----------------// /|\| XIN|-// | | |// --|RST XOUT|-// | |// | P1.0|---->LED// | | ####// | P1.2|----+--------#### Sensor#4// | | # ####// | | # R=5.1M// | | # ####// | P1.3|----+--------#### Sensor#3// | | ####// | |// | | ####// | P1.4|----+--------#### Sensor#2// | | # ####// | | # R=5.1M// | | # ####// | P1.5|----+--------#### Sensor#1// | | ####//// Zack Albus// Texas Instruments Inc.// June 2007// Built with IAR Embedded Workbench Version: 3.42A//***************************************************************************** *#include "msp430x20x3.h"// Define User Configuration values// Sensor settings#define Num_Sen 4 // Defines number of sensors#define S_4 (0x04) // Sensor 4 P1.2#define S_3 (0x08) // Sensor 3 P1.3#define S_2 (0x10) // Sensor 2 P1.4#define S_1 (0x20) // Sensor 1 P1.5#define LED (0x01) // P1.0#define min_KEY_lvl 30 // Defines the min key level threshold usable #define Sample_Rate 20 // Defines #/sec all sensors are sampled#define DCO_clks_per_sec 8000000 // Number of DCO clocks per second: 2MHz// Changes with DCO freq selected!#define DCO_clks_per_sample (DCO_clks_per_sec/Sample_Rate)/8// Clocks per sample cycle /8// /8 is allows integer usage// will be *8 in the final calcs#define LED_pulses_per_sample 5 // Defines LED pulses during each sample// -number of TACCR0 ints per sample#define Key_1_on_time 1 // Defines Key 4 % on#define Key_2_on_time 10 // Defines Key 3 % on#define Key_3_on_time 25 // Defines Key 2 % on#define Key_4_on_time 90 // Defines Key 1 % on// Global variables for sensingunsigned int dco_clks_per_vlo; // Variable used for VLO freq measurement unsigned int vlo_clks_per_sample; // Variable that determines vlo clocks per sample// vlo_clks_per_sample = DCO_clks_per_sample/dco_clks_per_vlo*8unsigned int vlo_clks_per_LED_pulse; // V ariable that determines vlo clocks per LED pulseunsigned int LED_on_time[Num_Sen]; // Stores calculated TACCR1 value for each// key separately. Calculated from//Key_x_on_time*vlo_clks_per_LED_pulse/100// Misc Globalsunsigned int base_cnt[Num_Sen];unsigned int meas_cnt[Num_Sen];int delta_cnt[Num_Sen];unsigned char key_press[Num_Sen];char key_pressed, key_loc, no_key, key_loc_old, key_time_out;char cycles;unsigned int timer_count;unsigned int KEY_lvl = 100; // Defines the min count for a "key press"// System Routinesvoid Init_Timings_Consts(void); // Use VLO freq to determine TA valuesvoid measure_count(void); // Measures each capacitive sensorextern unsigned int Measure_VLO_SW(void); // External function to measure// speed of the VLO// (implemented in Measure_VLO_SW.s43) // Main Functionvoid main(void){unsigned int i,j;int temp;// Configure clock systemWDTCTL = WDTPW + WDTHOLD; // Stop watchdog timerdco_clks_per_vlo = Measure_VLO_SW(); // Determine VLO freq for usageBCSCTL2 |= DIVM_2; // MCLK / 4BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHzDCOCTL = CALDCO_8MHZ; // MCLK = 8/4 = 2MHzBCSCTL3 |= LFXT1S_2; // LFXT1 = VLO// Configure GPIOsP1OUT = 0x00; // P1.x = 0P1DIR = 0xFF; // P1.x = outputP2OUT = 0x00;P2DIR = 0xFF; // P2.x = outputP2SEL = 0x00; // No XTAL__enable_interrupt(); // Enable interruptsInit_Timings_Consts();measure_count(); // Establish an initial baseline capacitancefor (i = 0; i<Num_Sen; i++)base_cnt = meas_cnt;for (i=15; i>0; i--) // Repeat and average base measurement{measure_count();for (j = 0; j<Num_Sen; j++)base_cnt[j] = (meas_cnt[j]+base_cnt[j])/2;}no_key = 0;// Main loop starts herewhile (1){key_pressed = 0; // Assume no keys are pressedmeasure_count(); // Measure all sensorsfor (i = 0; i<Num_Sen; i++){delta_cnt = meas_cnt - base_cnt; // Calculate delta: c_change// Handle baseline measurment for a base C decreaseif (delta_cnt < 0) // If negative: result decreased{ // below baseline, i.e. cap decreased base_cnt = (base_cnt+meas_cnt) >> 1; // Re-average baseline down quicklydelta_cnt = 0; // Zero out delta for position determination }if (delta_cnt > KEY_lvl) // Determine if each key is pressed per a preset threshold {key_press = 1; // Specific key pressedkey_pressed = 1; // Any key pressedkey_loc = i;}elsekey_press = 0;}// Handle baseline measurement for a base C increaseif (!key_pressed) // Only adjust baseline up if no keys are touched {key_time_out = Sample_Rate*3; // Reset key time out durationfor (i = 0; i<Num_Sen; i++)base_cnt = base_cnt + 1; // Adjust baseline up, should be slow to} // accomodate for genuine changes in sensor C else // Key pressed{if (key_loc_old == key_loc) // same key pressed?key_time_out--;elsekey_time_out = Sample_Rate*3; // Reset key time out durationkey_loc_old = key_loc;if (key_time_out == 0) // After time-out, re-init base and key levelWDTCTL = WDTHOLD; // FORCE RESET}// Dynamically adjust key thresholdsif (key_pressed && (delta_cnt[key_loc]>>2 > KEY_lvl)){temp = delta_cnt[key_loc]>>2;temp = temp + KEY_lvl;temp = temp>>1;KEY_lvl = temp; // Average result}else if (!key_pressed){for (i = 0; i<Num_Sen; i++){if(delta_cnt > min_KEY_lvl){temp = delta_cnt>>1; // Means min key level threshold = %50 of delta measuredtemp = temp + KEY_lvl; // or = min_KEY_lvl/2temp = temp>>1;KEY_lvl = temp; // Average resultbreak;}}}if (key_pressed) // Pulse LED and use defined sample rate{no_key = Sample_Rate*3; // Reset ~3 sec delay until slower sample rate is usedcycles = LED_pulses_per_sample; // Re-set LED pulse counterTACCTL0 = CCIE;TACCR0 = vlo_clks_per_LED_pulse; // Load LED pulse periodTACCTL1 = CCIE;TACCR1 = LED_on_time[key_loc]; // Load LED pulse duty cycleP1OUT |= LED; // Turn on LED}else // No key is pressed...{if (no_key == 0) // ...~3 sec timeout expired: no key press in ~3secs...{cycles = 1; // Adjust cycles for only one TA delayTACCTL0 = CCIE;TACCR0 = vlo_clks_per_LED_pulse*LED_pulses_per_sample*5; // Low sample rate to: sample_rate/5 SPS}else // ... still within 3 secs of last detected key press...{no_key--; // Decrement delaycycles = LED_pulses_per_sample; // Maintain sample_rate SPS, without LEDTACCTL0 = CCIE;TACCR0 = vlo_clks_per_LED_pulse;}P1OUT ^= BIT6; // Toggle P1.6 (for debug only)}TACTL = TACLR + TASSEL_1 + MC_1; // ACLK = VLO, up modeLPM3;}} // End Main// Measure count result (capacitance) of each sensor// Routine setup for four sensors, not dependent on Num_Sen value!void measure_count(void){unsigned char i;char active_key;TACTL = TASSEL_2+MC_2; // SMCLK, cont modefor (i = 0; i<Num_Sen; i++){active_key = 1 << i+2; // define bit location of active key//***************************************************************************** *// Negative cycle//***************************************************************************** *P1OUT &=~(S_1+S_2+S_3+S_4); // everything is low// Take the active key high to charge the padP1OUT |= active_key;// Allow a short time for the hard pull high to really charge the pad__no_operation();__no_operation();__no_operation();// Enable interrupts (edge set to low going trigger)// set the active key to input (was output high), and start the// timed discharge of the pad.P1IES |= active_key; //-ve edge triggerP1IE |= active_key;P1DIR &= ~active_key;// Take a snaphot of the timer...timer_count = TAR;LPM0;// Return the key to the driven low state, to contribute to the "ground"// area around the next key to be scanned.P1IE &= ~active_key; // disable active key interruptP1OUT &= ~active_key; // switch active key to low to discharge the keyP1DIR |= active_key; // switch active key to output low to save powermeas_cnt= timer_count;//**************************************************************************** // Positive Cycle//**************************************************************************** P1OUT |= (S_1+S_2+S_3+S_4); // everything is high// Take the active key low to discharge the padP1OUT &= ~active_key;// Allow a short time for the hard pull low to really discharge the pad__no_operation();__no_operation();__no_operation();// Enable interrupts (edge set to high going trigger)// set the active key to input (was output low), and start the// timed discharge of the pad.P1IES &= ~active_key; //+ve edge triggerP1IE |= active_key;P1DIR &= ~active_key;// Take a snaphot of the timer...timer_count = TAR;LPM0;// Return the key to the driven low state, to contribute to the "ground"// area around the next key to be scanned.P1IE &= ~active_key; // disable active key interruptP1OUT &= ~active_key; // switch active key to low to discharge the keyP1DIR |= active_key; // switch active key to output low to save powerP1OUT &=~(S_1+S_2+S_3+S_4); // everything is lowmeas_cnt = (meas_cnt + timer_count) >> 1; // Average the 2 measurements}TACTL = TACLR; // Stop the timer}void Init_Timings_Consts(void){// dco_clks_per_vlo = dco_clks_per_vlo << 1; // x2 for 2MHz DCO// dco_clks_per_vlo = dco_clks_per_vlo << 2; // x4 for 4MHz DCOdco_clks_per_vlo = dco_clks_per_vlo << 3; // x8 for 8MHz DCO// dco_clks_per_vlo = dco_clks_per_vlo << 4; // x16 for 16MHz DCOvlo_clks_per_sample = DCO_clks_per_sample/dco_clks_per_vlo*8;vlo_clks_per_LED_pulse = vlo_clks_per_sample/LED_pulses_per_sample;LED_on_time[0] = Key_1_on_time*vlo_clks_per_LED_pulse/100;if(LED_on_time[0] == 0)LED_on_time[0] = 1;LED_on_time[1] = Key_2_on_time*vlo_clks_per_LED_pulse/100;LED_on_time[2] = Key_3_on_time*vlo_clks_per_LED_pulse/100;LED_on_time[3] = Key_4_on_time*vlo_clks_per_LED_pulse/100;}// Port 1 interrupt service routine#pragma vector=PORT1_VECTOR__interrupt void port_1_interrupt(void){P1IFG = 0; // clear flagtimer_count = TAR - timer_count; // find the charge/discharge timeLPM0_EXIT; // Exit LPM0 on reti}// Timer_A0 interrupt service routine#pragma vector=TIMERA0_VECTOR__interrupt void Timer_A0 (void){cycles--;if (cycles > 0){if (key_pressed)P1OUT |= LED; // LED on for TACCR1 time of TA period }else{ TACTL = TACLR;TACCTL0 = 0; // interrupt disabledTACCTL1 = 0; // interrupt disabledLPM3_EXIT; // Exit LPM3 on reti}}// Timer_A1 interrupt service routine#pragma vector=TIMERA1_VECTOR__interrupt void Timer_A1 (void){TACCTL1 &= ~CCIFG; // Clear the flagP1OUT &= ~LED; // LED off for rest of TA period }。
msp430Led按键控制灯亮程序

1.Led灯控制程序#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD; //关闭看门狗//P1DIR = 0x41;//P1OUT = 0x41; //程序点亮led1//P1DIR |=BIT0+BIT6;//P1OUT |=BIT0+BIT6; //程序点亮led2P1DIR |=BIT0;P1OUT |=BIT0;P1DIR |=BIT6;P1OUT &=~BIT6;while(1){P1OUT ^=BIT0;P1OUT ^=BIT6;__delay_cycles(1000000);} //led交替亮,持续1s2.Led按键控制灯亮#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;//关闭看门狗P1DIR &=~BIT3;P1DIR |=BIT0;P1IES |=BIT3;P1IE |=BIT3;_EINT();_BIS_SR(LPM0_bits+GIE);}#pragma vector=PORT1_VECTOR__interrupt void PORT1_ISR(void){int i;char pushkey;pushkey=P1IFG&BIT3;//第三位中断标志位for(i=0;i<1000;i++)//短暂延时软件去抖if((P1IN&pushkey)==pushkey){P1IFG=0;//中断标志清零return;}if(P1IFG&BIT3)//判断按键是否按下{P1OUT^=BIT0;}P1IFG=0;return;}3.矩阵键盘和数码管程序#include <msp430g2553.h>#include"Key&Display.h"//unsigned char Receive(void);void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;Init_4lines_Mode();//初始化4线工作模式Send_Command(CH452_RESET);//CH452芯片内部复位Send_Command(KeyDisplay_ON);//允许显示驱动并启动键盘扫描//开中断,P2.0接CH452的DOUT引脚,当有键按下时,DOUT上产生由高到低的脉冲// P2SEL &= ~(BIT6+BIT7);P2IE|=BIT0;P2IES|=BIT0;P2IFG&=~BIT0;_EINT();while(1){}}//中断处理函数#pragma vector = PORT2_VECTOR//中断处理程序,接收到DOUT脉冲信号时,运行之__interrupt void Port2(void){unsigned char Keyvalue;Send_Command(CH452_GET_KEY);//单片机向CH452发送读取按键代码命令Keyvalue=Key_Read();// Keyvalue=Receive();switch(Keyvalue){case 0x40://按键K0按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis00);//第0位数码管显示0break;}case 0x41://按键K1按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis01);//第0位数码管显示1break;}case 0x42://按键K2按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis02);//第0位数码管显示2break;}case 0x43://按键K3按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis03);//第0位数码管显示3break;}case 0x48://按键K4按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis04);//第0位数码管显示4break;}case 0x49://按键K5按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis05);//第0位数码管显示5break;}case 0x4A://按键K6按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis06);//第0位数码管显示6break;}case 0x4B://按键K7按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis07);//第0位数码管显示7break;}case 0x50://按键K8按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis08);//第0位数码管显示8break;}case 0x51://按键K9按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis09);//第0位数码管显示9break;}case 0x52://按键K10按下{Send_Command(Dis00);//第0个数码管显示字符"0"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x53://按键K11按下{Send_Command(Dis01);//第0个数码管显示字符"1"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x58://按键K12按下{Send_Command(Dis02);//第0个数码管显示字符"2"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x59://按键K13按下{Send_Command(Dis03);//第0个数码管显示字符"3"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x5A://按键K14按下{Send_Command(Dis04);//第0个数码管显示字符"4"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x5B://按键K15按下{Send_Command(Dis05);//第0个数码管显示字符"5"Send_Command(Dis11);//第1个数码管显示字符"1"break;}default:break;}P2IFG&=~BIT0;}4.红灯0.2秒闪一次,绿灯0.8秒闪一次#include <msp430g2553.h>void main(void){WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 &=~XTS; //配置时钟BCSCTL3 |=LFXT1S_2;IFG1 &=OFIFG;P1DIR |=BIT0+BIT6; // P1.0,P1.6 output P1OUT &=~BIT0; // P1.0,P1.6置0 P1OUT &=~BIT6;TACCR0 = 12000-1; //1秒定时,产生中断TACCR1 = 2400; //频率0.2*12000,定时0.2秒TACCR2 = 9600; //定时0.8秒TACTL = TASSEL_1 + MC_1+TAIE; // ACLK, 增计数模式TACCTL1 |=CCIE; // TACCR1中断使能TACCTL2 |=CCIE; // TACCR1中断使能_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt}// Timer_A3 Interrupt Vector (TA0IV) handler#pragma vector=TIMER0_A1_VECTOR__interrupt void Timer_A(void){switch( TA0IV ){case 2: P1OUT ^= BIT0; // 捕获/比较寄存器TACCR1break;case 4: P1OUT ^= BIT6;break; // 捕获/比较寄存器TACCR2case 10: break; // 未使用,计数达到TACCRO时执行中断,即1秒执行一次}}5.PMW波控制led灯亮度#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;P1DIR |=BIT6; //方向寄存器P1SEL |=BIT6; //功能寄存器TACTL=TASSEL_2+MC_1+ID_0; //定时器A控制寄存器选择增计数模式TACCTL1 |=OUTMOD_3; //捕获/比较控制寄存器TACCR0=1000-1;TACCR1=10;_BIS_SR(CPUOFF);}。
msp430全部基础程序集合

本文档由“X-TAB论坛”提供()1 [入门必修]按键检测与程序结构...菜菜//// MC430F224// -----------------// /|\| |// | | |// --|RST in1 |--~^~-------|GND KEY1 1// | in2 |--~^~-------|GND KEY2// | in3 |--~^~-------|GND KEY3// | |// | out1 |------|<|---|Vcc D1 LED// | out2 |------|<|---|Vcc D2 LED// | out3 |------|<|---|Vcc D3 LED////************************MC430F224*********************** *********************#includ e <msp430x22x4.h>//初级用户要习惯采用宏定义,以方便的编写和修改#define keyio 0xf1 //定义按键IO口,所有键口为0.#define key_1 0xfd //定义返回键值1#define key_2 0xfb //定义返回键值2#define key_3 0xf7 //定义返回键值3#define LED_D1_flas h P1OUT^= BIT1#define LED_D2_flas h P1OUT^= BIT2#define LED_D3_flas h P1OUT^= BIT3#define bell_d elay7000//声明子程序unsign ed char key_ch cek(void);void displa y_upd ate(unsign ed char dta);void key_pr ocess_0(void);void key_pr ocess_1(void);void key_pr ocess_2(void);//********************************************************** ***************//将单片机初始化程序放在m ain()前面是方便查看单片机的初始化状态情况.void MCU_in t(void){//默认MCLK主时钟频率为DCO=~800KP1OUT|= BIT1+BIT2+BIT3; //设置LED,上电为灭.电路可以查看M C430F14电路图.P1DIR|= BIT1+BIT2+BIT3; //P1.1设置为输出.//MSP430单片机IO口上电默认方向为输入,所以接按键的I O无需再设为输入.}//********************************************************** ***************void main (void){ unsign ed char key_va lue; //定义键值全局变是WDTCTL = WDTPW + WDTHOL D;//关狗MCU_in t(); //初始化单片机while(1) //主程序主循环{key_va lue=key_ch cek(); //检测,有键按下并松开,返回一个键值.switch(key_va lue) //对键值进行处理.采switc h 语法结构查询{case key_1: key_pr ocess_0(); //调用键处理程序1b reak;case key_2: key_pr ocess_1(); //调用键处理程序2b reak;case key_3: key_pr ocess_2(); //调用键处理程序2b reak;defaul t: ; //调用键处理程序4b reak;}displa y_upd ate(key_va lue); //如果有需要可以在这里加上显示更新程序.key_value=0x00; //最后清除键值.将继续主循环.}}//********************************************************** ***************//按键检测程序//返回值: 无符号字符型键值unsign ed char key_ch cek(void){unsign ed int i;unsign ed char timp,active;active=0;while(!active){while(0xff ==( P2IN | keyio)); //一直等待有键按下timp = P2IN | keyio;//若有键接下了,则读入IO状态.for(i=0;i<7000;i++); //延时,是为了去按键抖动.if (timp ==(P2IN | keyio))//经延时后,还是那键吗?{ active = 1; //是,则按键有效.while(0xff !=( P2IN | keyio)); //一直等待按键松开}else{ //去按键抖动后读入的键值与之前不同.则先效.active = 0; //再循环检测.}}return timp; //返回一个键值.}//********************************************************** ***************void key_pr ocess_0(void) //值处理,用户可以自己修改... {LED_D1_flas h;}//********************************************************** ***************void key_pr ocess_1(void) //值处理,用户可以自己修改... {LED_D2_flas h;}//********************************************************** ***************void key_pr ocess_2(void) //值处理,用户可以自己修改... {LED_D3_flas h;}//********************************************************** ***************void displa y_upd ate(unsign ed char dta){; //用户可以根据需要来放置显示程序,如LCD,LED,Digita l-LED....//灵活应用,}//********************************************************** ***************2 [入门必修]串行异步通讯例子..菜菜微控网原创复制代码//********************************************************** ******************//描述:在微控MC430F224开发板上实现UAR T模块串行异步通讯实验。
MSP430 键盘程序

/*MSP430F42X系列单片机16位ADC通用程序库说明:该驱动程序库包含了常用的16位ADC操作与控制功能函数,如选择通道、设置信号放大/*带有缓冲区及长短键的键盘通用程序库说明:该程序库包含了读取键盘的相关函数,并且包含了一个键盘缓冲区,当主程序执行较慢,而遇到连续快速的键盘输入来不及及时读取的情况下,新的按键信息将会自动存入键盘缓冲队列内,每次调用读键盘函数时会依顺序读取,保证键盘操作不会丢失。
并且带有长短按键识别功能,当按键时间小于2秒时,返回短键,按键超过2秒后,每隔0.25秒返回一次长按键。
该键盘程序可以作为各种程序的底层驱动使用。
要使用该库函数,需要将本文件(Key.c)添加进工程,并在需要调用键盘函数的文件开头处包含"Key.h";还需要开启一个定时器,在定时中断内调用Key_ScanIO()函数。
设置定时中断的频率在16~128次/秒之间。
*///+-------------+//|定时中断|软件结构//+-------------+//|//+-------------++-------------++-------------+// KEY1_IN -->| Key_ScanIO||KeyBuff[]||Key_GetKey() |// KEY2_IN -->|键盘扫描|-->|键盘缓冲|-->|Key_WaitKey()|-->应用程序// KEY3_IN -->|函数||队列(FIFO) ||键盘读取函数|//+-------------++-------------++-------------+//////MSP430F4XX//+---------------+//+---KEY1--|P1.5|//||XOUT|-----//+---KEY2--|P1.6|32.768KHz Watch Crystal//||XIN|-----//+---KEY3--|P1.7|//|+---------------+//GND//#include<msp430x42x0.h>#define KEYBUFF_SIZE8/*键盘缓冲区大小,根据程序需要自行调整*/ char KeyBuff[KEYBUFF_SIZE]; //定义键盘缓冲队列数组(FIFO)char Key_IndexW=0;//键盘缓冲队列写入指针(头指针)char Key_IndexR=0;//键盘缓冲队列读取指针(尾指针char Key_Count=0;//键盘缓冲队列内记录的按键次数char KEY1_State=0;char KEY2_State=0;char KEY3_State=0;/*3个按键的状态变量*/#define NOKEY0#define PUSH_KEY1#define LONG_PUSH 2#define KEY1_IN (P5IN&BIT5) //KEY1输入IO的定义(P6.4)#define KEY2_IN (P5IN&BIT6) //KEY2输入IO的定义(P6.5)#define KEY3_IN (P5IN&BIT7) //KEY3输入IO的定义(P6.6)#define KEY1 0x01//SET按键#define KEY2 0x02//增加按键#define KEY3 0x04//减小按键#define LONG0x80/*连续长键标志位宏定义*/#define FIRSTLONG 0xC0/*首次长键标志位宏定义*//***************************************************************** ************名称:Key_InBuff()*功能:将一次键值压入键盘缓冲队列*入口参数:Key:被压入缓冲队列的键值*出口参数:无********************************************************************* *******/void Key_InBuff(char Key){if(Key_Count>=KEYBUFF_SIZE) return;//若缓冲区已满,放弃本次按键_DINT();Key_Count++;//按键次数计数增加KeyBuff[Key_IndexW] = Key;//从队列头部追加新的数据if (++Key_IndexW >=KEYBUFF_SIZE) //循环队列,如果队列头指针越界{Key_IndexW = 0;//队列头指针回到数组起始位置}_EINT();}/*********************************************************** ******************名称:Key_GetKey()*功能:从键盘缓冲队列内读取一次键值*入口参数:无*出口参数:若无按键,返回0,否则返回一次按键键值。
MSP430程序HD7279键盘程序

//HD7279键盘程序#include "msp430g2452.h"#include "HD7279.h"static void delay_us(uint16 n) //N us延时函数{for(; n>0; n--);}void HD7279_Init(void){//HD7279_DIR |= HD7279_CS + HD7279_CLK + HD7279_DATA;HD7279_DIR |= HD7279_CLK + HD7279_DATA;HD7279_DIR &= ~HD7279_KEY;HD7279_IES |= HD7279_KEY; // 下降沿触发方式HD7279_IFG &= ~HD7279_KEY; // 清空中断标志HD7279_IE |= HD7279_KEY; // 使能KEY 中断//SendByte(0xA4); //清除缓存指令}/***发送一个字节的数据***/void SendByte(uint8 byte){uint8 i;HD7279_DIR |= HD7279_DA TA;HD7279_CLK_0;//HD7279_CS_0;delay_us(40);for (i=0;i<8;i++){if (byte&0x80)HD7279_DA TA_1;elseHD7279_DA TA_0;delay_us(1);HD7279_CLK_1;delay_us(12);HD7279_CLK_0;delay_us(12);byte = byte<<1;}HD7279_DATA_0;//HD7279_CS_1;}/***接收一个字节的数据***/uint8 ReceiveByte(void){uint8 i, state, out_byte;HD7279_CLK_0;HD7279_DIR &= ~HD7279_DATA;//HD7279_CS_0;delay_us(40);for (i=0;i<8;i++){HD7279_CLK_1;delay_us(12);out_byte=out_byte<<1;state = HD7279_IN & HD7279_DA TA;if (state == HD7279_DATA){out_byte=out_byte|0x01;}HD7279_CLK_0;delay_us(12);}//HD7279_CS_1;return (out_byte);}//写带数据的指令void write_7279(uint8 cmd, uint8 dat){SendByte(cmd);SendByte(dat);}uint8 read_7279(void){SendByte(0x15); // 发送读命令return (ReceiveByte());}/*void HD7279_disp(unsigned int disp_data){unsigned char shiwan,wan,qian,bai,shi,ge;unsigned int temp;temp = disp_data;shiwan = temp/100000;wan = temp%100000/10000;qian = temp%100000%10000/1000;bai = temp%100000%10000%1000/100;shi = temp%100000%10000%1000%100/10;ge = temp%100000%10000%1000%100%10;write_7279(0x80,ge);write_7279(0x81,shi);write_7279(0x82,bai);write_7279(0x83,qian);write_7279(0x84,wan);write_7279(0x85,shiwan);}*/uint8 Get_7279_KeyData(void){uint8 key_data, key_value;key_data = read_7279();if ((key_data < 8) && (key_data > 3))key_value = 8 - key_data;else if ((key_data < 16) && (key_data > 11))key_value = 20 - key_data;else if ((key_data < 24) && (key_data > 19))key_value = 32 - key_data;else if ((key_data < 32) && (key_data > 27))key_value = 44 - key_data;elsekey_value = 0;return (key_value);}//12864程序#include "msp430g2452.h"#include "12864.h"static void delay(uint16 t){unsigned int i,j;for(i=0; i<t; i++)for(j=0; j<14; j++);}void sendbyte(uint8 zdata){uint8 i;for(i=0; i<8; i++){if((zdata << i) & 0x80)SID_1;elseSID_0;SCLK_0;SCLK_1;}}void write_com(uint8 cmdcode){//CS_1;sendbyte(0xf8);sendbyte(cmdcode & 0xf0);sendbyte((cmdcode << 4) & 0xf0);delay(2);}void write_data(uint8 Dispdata){//CS_1;sendbyte(0xfa);sendbyte(Dispdata & 0xf0);sendbyte((Dispdata << 4) & 0xf0);delay(2);}void LCD_Init(void){LCD_DIR |= (LCD_SID + LCD_SCK);delay(2000);write_com(0x30);delay(50);write_com(0x0c);delay(50);write_com(0x01);//清屏delay(50);write_com(0x06);//00000110); //光标右移//06 delay(100);}void LCD_SetPosition(uint8 x,uint8 y){uint8 pos;if(x == 0)x = 0x80;else if(x == 1)x = 0x90;else if(x == 2)x = 0x88;else if(x == 3)x = 0x98;pos = x + y;write_com(pos);//显示地址}void LCD_DisplayString(uint8 *s){while(*s > 0){write_data(*s);s++;delay(50);}}void LCD_DisplayNumber(uint32 num, uint8 len){uint8 wei[10];uint8 i;uint8 flag = 0;for (i = 0; i < len; i++){wei[i] = num%10;num = num/10;}for (i = len; i > 0; i--){if ((wei[i-1] == 0) && (flag == 0) && (i > 1))write_data(' ');else if(wei[i-1] != 0)flag = 1;if (flag)write_data(wei[i-1]+0x30);}if (flag == 0)write_data('0');}void LCD_DisplayXiaoshu(uint32 num, uint8 len) {uint8 wei[10];uint8 i;for (i = 0; i < len; i++){wei[i] = num%10;num = num/10;}write_data('.');for (i = len; i > 0; i--){write_data(wei[i-1]+0x30);}}。
MSP430中断小实验——通过按键改变小灯闪烁频率

MSP430中断⼩实验——通过按键改变⼩灯闪烁频率本⼩实验基于MSP430f5529,不同的型号可能管脚和中断配置有所不同。
实现的功能为:第⼀次按下按键后,系统以每 2 秒钟,指⽰灯暗 1 秒,亮 1 秒的⽅式闪烁。
程序采⽤默认时钟配置;第⼆次按下按键后,系统以每 4 秒钟,指⽰灯亮 2 秒,暗 2 秒钟⽅式闪烁。
第三次按下按键后,系统以每 4 秒钟,指⽰灯亮 1 秒,暗 3 秒⽅式闪烁。
程序基于定时器配置。
/** main.c* 第⼀次按下按键后,系统以每 2 秒钟,指⽰灯暗 1 秒,亮 1 秒的⽅式闪烁,程序采⽤默认时钟配置;第⼆次按下按键后,系统以每 4 秒钟,指⽰灯亮 2 秒,暗 2 秒钟⽅式闪烁。
第三次按下按键后,系统以每 4 秒钟,指⽰灯亮 1 秒,暗 3 秒⽅式闪烁,程序基于定时器配置。
*/#include <msp430f5529.h>int count = 0; //计数int t1_50ms = 20; //⼀个单位对应50ms(亮)int t2_50ms = 20; //⼀个单位对应50ms(灭)int flag = 0; //闪烁频率标志int flag_t = 1; //亮灭标志int main(void) {WDTCTL = WDTPW+WDTHOLD;//时钟中断配置P1DIR |= BIT0;TA0CCTL0 = CCIE;//使能定时器中断TA0CCR0 = 50000;TA0CTL = TASSEL_2 + MC_1 + TACLR;//配置为SMCLK,升计数模式,初始化时钟//S1配置P1IE |= BIT7; //允许P1.7中断P1IES |= BIT7; //设置为下降沿中断P1IFG &= ~BIT7; //设置为输⼊P1REN |= BIT7; //启⽤上下拉电阻P1OUT |= BIT7; //将电阻设置为上拉__bis_SR_register(LPM0_bits+GIE); //打开中断return 0;}#pragma vector=TIMER0_A0_VECTOR__interrupt void TIMER0_A0_ISR(void){if(count==t1_50ms&&flag_t==1) //灯亮{P1OUT |= BIT0;count=0;flag_t=0;}else if(count==t2_50ms&&flag_t==0) //灯灭{P1OUT &=~BIT0;count = 0;flag_t=1;}else count++;}#pragma vector=PORT1_VECTOR;__interrupt void botton (void){__delay_cycles(75);//延时消抖switch(flag)//flag决定闪烁频率{case 0:t1_50ms = 20;t2_50ms = 20;break;//1秒亮 1秒暗case 1:t1_50ms = 40;t2_50ms = 40;break;//2秒亮 2秒暗case 2:t1_50ms = 60;t2_50ms = 20;break;//3秒亮 3秒暗}flag++;//状态变化if(flag>2) flag = 0;//flag归位P1IFG &=~ BIT7; //清除中断标志位__bis_SR_register(LPM0_bits+GIE);//打开中断}。
MSP430F149的定时器A操作

MSP430F149的定时器A定时操作1)定时器A的图解图1 定时器A图解2)定时器A的四种计数模式。
1.停止模式。
2.增计数模式。
(产生两个中断标志)也就是当计数到跟TACCR0一样的时候,就返回0,重新计数。
当计数到TACCR0的同时产生一个中断标志CCIFG,而当计数器溢出返回零的同时又同时产生一个中断标志TAIFG。
如图:图2 增计数模式的波形图3.连续计数模式。
(产生一个中断标志)也就是计数器将直接计数到计数器所能计数的最大值0FFFFH之后重新返回零,再次计数。
返回零的同时产生一个TAIFG中断标志。
如图:4.增减计数模式。
(产生两个中断标志)也就是当计数器计数到跟TACCR0一样的之后,然后从TACCR0开始又减少,直到为零,然后又开始增。
当计数跟TACCT0一样的时候产生一个中断标志CCIFG,当减到为零的时候又产生一个中断标志TAIFG。
如图:注意:当重新写入TACCR0数值的时候,当新的数据大于原来的数值的时候,计数器将计数到新的数值才重新返回零;当新的数据小于原来的数值的时候,计数器将直接返回零重新计数。
3)定时器A的寄存器。
1.TACTL●TASSELx:计时器A的时钟来源选择。
●IDx:计时器A时钟的分频选择。
●MCx:计时器A四种计数模式选择。
●TACLR:计数器A的TAR计数清零,同时也可以清楚时钟分频器和计数方向。
●TAIE:TAIFG中断标志使能。
在捕获模式下可以打开所有CCIFG的中断使能。
●TAIFG:中断标志位。
2.TAR计数器的计数寄存器。
3.TACCTLx●CMx:捕获模式选择。
00:关闭;01:上升沿捕获;10:下降沿捕获;11:上升下降沿捕获。
●CCISx:捕获引脚选择。
●SCS:选择捕获电平方式。
0异步时钟;1同步时钟。
●SCCI:锁存同步时钟输入端。
也就是锁存EQUx的值,以供CPU读取。
●CAP:捕获模式和比较模式选择。
0比较;1捕获。
●OUTMODx:输出模式选择。
MSP430按键程序范例(附原理图)

MSP430按键程序范例(附原理图)#i ncludevoid Init_Port(void){//将P1口所有的管脚在初始化的时候设置为输入方式 P1DIR = 0; //将P1口所有的管脚设置为一般I/O口P1SEL = 0;// 将P1.4 P1.5 P1.6 P1.7设置为输出方向P1DIR |= BIT4;P1DIR |= BIT5;P1DIR |= BIT6;P1DIR |= BIT7;//先输出低电平P1OUT = 0x00;// 将中断寄存器清零P1IE = 0;P1IES = 0;P1IFG = 0;//打开管脚的中断功能//对应的管脚由高到低电平跳变使相应的标志置位P1IE |= BIT0;P1IES |= BIT0;P1IE |= BIT1;P1IES |= BIT1;P1IE |= BIT2;P1IES |= BIT2;P1IE |= BIT3;P1IES |= BIT3;_EINT();//打开中断return;}void Delay(void){int i;for(i = 100;i--;i > 0) ;//延时一点时间}int KeyProcess(void){int nP10,nP11,nP12,nP13;int nRes = 0;//P1.4输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 13; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 14; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 15; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 16; //P1.5输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 9; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 10; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 11; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 12; //P1.6输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 5; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 6; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 7; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 8; //P1.7输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 1; nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 2; nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 3; nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 4; P1OUT = 0x00;//恢复以前值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#i nclude <MSP430x14x.h>
void Init_Port(void)
{
//将P1口所有的管脚在初始化的时候设置为输入方式 P1DIR = 0;
//将P1口所有的管脚设置为一般I/O口
P1SEL = 0;
// 将P1.4 P1.5 P1.6 P1.7设置为输出方向
P1DIR |= BIT4;
P1DIR |= BIT5;
P1DIR |= BIT6;
P1DIR |= BIT7;
//先输出低电平
P1OUT = 0x00;
// 将中断寄存器清零
P1IE = 0;
P1IES = 0;
P1IFG = 0;
//打开管脚的中断功能
//对应的管脚由高到低电平跳变使相应的标志置位
P1IE |= BIT0;
P1IES |= BIT0;
P1IE |= BIT1;
P1IES |= BIT1;
P1IE |= BIT2;
P1IES |= BIT2;
P1IE |= BIT3;
P1IES |= BIT3;
_EINT();//打开中断
return;
}
void Delay(void)
{
int i;
for(i = 100;i--;i > 0) ;//延时一点时间
}
int KeyProcess(void)
{
int nP10,nP11,nP12,nP13;
int nRes = 0;
//P1.4输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 13; nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 14; nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 15; nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 16; //P1.5输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 9; nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 10; nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 11; nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 12; //P1.6输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 5; nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 6; nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 7; nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 8; //P1.7输出低电平
P1OUT &= ~(BIT4);
nP10 = P1IN & BIT0;
if (nP10 == 0) nRes = 1; nP11 = P1IN & BIT1;
if (nP11 == 0) nRes = 2; nP12 = P1IN & BIT2;
if (nP12 == 0) nRes = 3; nP13 = P1IN & BIT3;
if (nP13 == 0) nRes = 4; P1OUT = 0x00;//恢复以前值。
//读取各个管脚的状态
nP10 = P1IN & BIT0;
nP11 = P1IN & BIT1;
nP12 = P1IN & BIT2;
nP13 = P1IN & BIT3;
for(;;)
{
if(nP10 == 1 && nP11 == 1 && nP12 == 1 && nP13 == 1) {
//等待松开按键
break;
}
}
return nRes;
}
// 处理来自端口 1 的中断
interrupt [PORT1_VECTOR] void PORT_ISR(void)
{
Delay();
KeyProcess();
if(P1IFG & BIT0)
{
P1IFG &= ~(BIT0);// 清除中断标志位
}
if(P1IFG & BIT1)
{
P1IFG &= ~(BIT1);// 清除中断标志位
}
if(P1IFG & BIT2)
{
P1IFG &= ~(BIT2);// 清除中断标志位
}
if(P1IFG & BIT3)
{
P1IFG &= ~(BIT3);// 清除中断标志位
}
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1
BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}。