msp430 按键控制LED 最基本程序
430单片机点亮LED实验报告
430单片机点亮LED实验报告一.安装实验软件IAR二.编写点亮LED灯程序1.使P1.0口LED灯会不停的闪烁着,程序#include <msp430x14x.h>typedef unsigned int uint;typedef unsigned char uchar;/*延时函数*/void Delay_Ms(uint x){uint i;while(x--)for(i=0;i<250;i++);}/*主函数*/int main( void ){WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer to prevent time out resetP2DIR|=BIT0;//定义P1口为输出while(1)//死循环{P2OUT^=BIT0;//P1.0口输出取反Delay_Ms(600);//稍作延时}}下载进去看到了P1.0口LED灯会不停的闪烁着。
2.实验目的让两盏灯交换闪烁程序#include"msp430g2553.h"void main(void) {void Blink_LED();WDTCTL=WDTPW+WDTHOLD; //关闭看门狗P1DIR=BIT6;P2DIR=BIT0;while(1){Blink_LED();}}void Blink_LED(){_delay_cycles(1000000); //控制第二个LED P1OUT^=BIT6;_delay_cycles(1000000); //控制第一个LEDP2OUT^=BIT0;}我编写这段程序的现象是一个灯先亮,另一个后亮,一个灯先灭,后一个再灭。
就是两个灯的状态没有做到相反。
后来我在我程序上做了一些改动。
#include"msp430g2553.h"void main(void) {void Blink_LED();WDTCTL=WDTPW+WDTHOLD; //关闭看门狗P1DIR=BIT6;P2DIR=BIT0;P1OUT |= BIT6;P2OUT &= ~BIT6;while(1){Blink_LED();}}void Blink_LED(){_delay_cycles(1000000); //控制第二个LEDP1OUT^=BIT6;P2OUT^=BIT0;}3.LED灯逆循环点亮程序#include <reg52.h>typedef unsigned char uint8; typedef unsigned int uint16; sbit ENLED1=P1^4;sbit ENLED2=P1^3;sbit ADDR0 =P1^0;sbit ADDR1 =P1^1;sbit ADDR2 =P1^2;main(){uint16 i;uint8 j;ENLED1=0; ENLED2=1;ADDR0=0; ADDR1=1; ADDR2=1; while(1){P0=~(80>>j++);for(i=1;i<20000;i++);if(j==8)j=0;}}我写好程序了可是运行的时候结果不对),之后继续修改程序while循环都没有对LED的串口做任何处理,把“P0=~(80>>j++); ”改成“P0=~(0x80>>j++); ”#include <reg52.h>typedef unsigned char uint8;typedef unsigned int uint16;sbit ENLED1=P1^4;sbit ENLED2=P1^3;sbit ADDR0 =P1^0;sbit ADDR1 =P1^1;sbit ADDR2 =P1^2;main(){uint16 i;uint8 j;ENLED1=0; ENLED2=1;ADDR0=0; ADDR1=1; ADDR2=1;while(1)P0=~(0x80>>j++); //P0=~(80>>j++);for(i=1;i<20000;i++);if(j==8){j=0;}}四.实验总结由于之前学过一段时间51单片机,所以有些东西比较清楚,但430和51一有很大不同,虽然内部结构很像,但430的寄存器的设置很麻烦,比如P1 P2口,那可真是麻烦得很,430这个IO口设置了如很多的功能,并且单独抽出了好几个设置的寄存器。
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 }。
单片机独立按键控制led灯实验原理
主题:单片机独立按键控制LED灯实验原理目录1. 概述2. 单片机独立按键控制LED灯实验原理3. 实验步骤4. 结语1. 概述单片机在现代电子设备中起着至关重要的作用,它可以通过编程实现各种功能。
其中,控制LED灯是单片机实验中常见的任务之一。
本文将介绍单片机独立按键控制LED灯的实验原理及实验步骤,希望对初学者有所帮助。
2. 单片机独立按键控制LED灯实验原理单片机独立按键控制LED灯的实验原理主要涉及到单片机的输入输出端口及按键和LED的连接方式。
在单片机实验中,按键与单片机的输入端口相连,LED与单片机的输出端口相连。
通过按键的按下和松开来改变单片机输出端口电平,从而控制LED的亮灭。
3. 实验步骤为了完成单片机独立按键控制LED灯的实验,需要按照以下步骤进行操作:步骤一:准备材料- 单片机板- 按键- LED灯- 连线- 电源步骤二:搭建电路- 将按键与单片机的输入端口相连- 将LED与单片机的输出端口相连- 连接电源步骤三:编写程序- 使用相应的单片机开发软件编写程序- 程序中需要包括按键状态检测和LED控制的部分步骤四:烧录程序- 将编写好的程序烧录到单片机中步骤五:运行实验- 按下按键,观察LED的亮灭情况- 确保按键可以正确控制LED的亮灭4. 结语通过上述实验步骤,我们可以实现单片机独立按键控制LED灯的功能。
这个实验不仅可以帮助学习者了解单片机的输入输出端口控制,还可以培养动手能力和程序设计能力。
希望本文对单片机实验初学者有所帮助,谢谢阅读!实验步骤在进行单片机独立按键控制LED灯实验时,需要按照一定的步骤进行操作,以确保实验能够顺利进行并取得预期的效果。
下面将详细介绍实验步骤,帮助读者更好地理解和掌握这一实验过程。
1. 准备材料在进行单片机独立按键控制LED灯实验前,首先需要准备相应的材料。
这些材料包括单片机板、按键、LED灯、连线和电源。
在选择单片机板时,需要根据具体的实验需求来确定,常见的有51单片机、Arduino等,不同的单片机板具有不同的特性和使用方法,因此需要根据实验要求来选择适合的单片机板。
msp430f5438使用说明.
MSP430F5438 开发板使用说明
1.电源
开发板使用DC5V的外部供电,跳线J3实现了开关功能。
电源接通后D6的LED点亮。
2. 复位按键
S13为复位按键。
按下复位按钮,即可将程序复位,从头开始执行。
3.键盘
开发板设有12个按键,为3*4的行列扫描键盘。
使用P3.0到P3.7端口,P3.0、P3.1、P3.2为行线,P3.4、P3.5、P3.6、P3.7为列线。
列线分别由上拉电阻拉到VCC,在行线与列线的每一个交接处有一个按键,按键的两端分别接在行线和列线上。
如果有键按下,则与只相连的行线与列线被连通,即可检测按键。
4.LCD显示
表1:12864LCD的引脚说明
IO口连接
P9.5------RS P9.6------R\W P9.7------E P10.0~10.7--------DB0~DB7 P11.0-------CS1 P11.1-------CS2 P11.2------RST
跳线J4是背光开关;
电位器R13背光亮度调节。
5.LED
P9.0 9.1 9.2 9.3 9.4 口接有LED,设置各口为输出高电平时LED点亮,低电平时熄灭。
6.扩展IO口
开发板两侧的双排插针。
MSP430F5438管脚。
msp430-流水灯
实验一流水灯实验一.实验内容与目的1.实验内容实现LED灯的顺次点亮。
2.实验目的对msp430有初步了解,学会msp430I/O口的使用方法,了解msp430的内部资源,学习尝试使用msp430的时钟、中断。
二.方法与结果用P2口对led的亮灭进行控制(对P2口赋值为0时led点亮,电路图如下),使用msp430比较器0和定时器产生1s的定时,当定时到1s时改变led的状态(流程图如下)。
三.实现程序#include<msp430.h>void main( ){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗中断P2DIR=0xff; //设定P2口为输出P1SEL=0x00; //设定P2口为普通I/O口CCTL0=CCIE; //开启比较器0中断CCR0=32768; //定时时间的选取,当计数器TAR计数到CCR0时,跳到中断TACTL=TASSEL_1+MC_1;//TACTL是计数器的控制寄存器,选择时钟系统,计数方式P2OUT=0xfe; //设定P2口初值_EINT(); //开启总中断LPM3; //进入低损耗模式}#pragma vector=TIMERA0_VECTOR__interrupt void timer() //中断程序{if(P2OUT==0x7f){P2OUT=0xfe;}else{P2OUT=P2OUT<<1;P2OUT=P2OUT|0x01; //位操作,改变led的状态}}四.流水灯实验总结①msp430的P1~P6口都可以用作I/O口,但msp430不能利用对I/O口直接赋值的方法控制I/O口的输出、接收I/O口的输入,而是利用相应的寄存器(PxOUT 和PxIN),对PxOUT赋值就完成了I/O口的输出,将PxIN的值赋给相应变量就完成了I/O口的输入。
另外msp430还有I/O口控制寄存器,PxDIR和PxSEL,PxDIR控制I/O口的输出输入,赋值为‘1’表示输出。
使用按键控制LED灯亮—按键控制LED灯亮灭程序编写
9课Βιβλιοθήκη 任务编写由一个按键按制一个 LED 灯,当 按键按下时,LED 灯亮再按时 LED 灯 灭的 C 语言程序。
单片机技术及应用
单片机技术及应用
1
工作任务
任务要求:
当独立按
键 key 按下时, 发光二极管
LED 点亮,松 开按键 key 时 发光二极管
LED 熄灭。
任务分析:
按下
P3.0端口为“0”
程
亮
按键Key
序 控
松开
P3.0端口为“0”
制
灭
2
程序设计流程
一、流程图
二、按键软件延时消抖
1.延时程序编写
void delay(uint x)//ms延时函数 { uchar i; while(x--) for(i=0;0<i<123;i++)
下载程序及硬件调试
1.下载程序
2.连接电路
电路连接表
控制端口
连接位置
P1.0
VD26
P3.0
KEY1
3.硬件调试
7
成果展示及评价
•学生进行作品展示
8
任务小结
•学生小结:小组代表总结本组的学习心得,学会了什么, 还有什么没有理解等等。 •教师小结:教师对每组的成果进行点评,并对本节课的知识 点进行总结。
while(1) {
if(key==0) { delay(10); if(key==0) { 灯亮;} } } else {灯灭;} }
4 程序仿真调试
一、利用Proteuse软件绘制电路图
步骤: 打开Protues 软件 创建工程 创建文件 放置元件 连接电路 保存
二、装载Hex文件并仿真
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单片机入门例程
MSP430单片机入门例程MSP430单片机是一款低功耗、高性能的16位单片机,广泛应用于各种嵌入式系统。
下面是一个简单的MSP430单片机入门例程,可以让大家初步了解MSP430单片机的基本使用方法。
所需材料:1、MSP430单片机开发板2、MSP430单片机编译器3、MSP430单片机调试器4、电脑和相关软件步骤:1、安装MSP430单片机编译器首先需要安装MSP430单片机的编译器,该编译器可以将C语言代码编译成MSP430单片机可以执行的机器码。
在安装编译器时,需要选择与您的单片机型号匹配的编译器。
2、编写程序下面是一个简单的MSP430单片机程序,可以让LED灯闪烁:c本文include <msp430.h>int main(void)本文P1DIR |= 0x01; //设置P1.0为输出while(1){P1OUT ^= 0x01; //反转P1.0的状态,LED闪烁__delay_cycles(); //延时一段时间,控制闪烁频率}本文上述程序中,首先定义了P1DIR寄存器,将P1.0设置为输出。
然后进入一个无限循环,在循环中反转P1.0的状态,使LED闪烁。
使用__delay_cycles()函数实现延时,控制LED闪烁频率。
3、编译程序使用MSP430单片机编译器将程序编译成机器码,生成可执行文件。
在编译时,需要注意选择正确的编译器选项和单片机型号。
4、调试程序使用MSP430单片机调试器将可执行文件下载到单片机中,并使用调试器进行调试。
在调试时,可以观察单片机的输出口状态和LED灯的闪烁情况,确保程序正常运行。
随着嵌入式系统的发展,MSP430单片机作为一种低功耗、高性能的微控制器,在各种应用领域中得到了广泛的应用。
为了更好地理解和应用MSP430单片机,我在学习过程中积累了一些经验,现在分享给大家。
MSP430单片机是一种超低功耗的微控制器,由德州仪器(Texas Instruments)推出。
MSP430单片机在调控LED植物智能补光系统中的应用
MSP430单片机在调控LED植物智能补光系统中的应用中国是一个发展中的农业大国,农业问题始终是关系到中国经济社会发展的根本问题。
在我国, 农业的现状在极大程度上依然按传统方式, 高成本, 低效率, 投入较高, 产值较低, 这些特征使得农业成为国民经济中亟待发展的一环。
科学研究表明,光照度和光质对植物的光合作用、生长发育、物质代谢及结构形态等具有重要影响,其中380~760 nm 可见光波段是决定光合作用最重要的光照波段,但有效吸收波段主要为其中红、蓝两波段。
对农作物使用红、蓝光进行补光,使其处于最佳生长环境中,可以很大程度提高农作物产量,缓解我国的农业问题,为人们提供更加新鲜、高质量与高效的农产品。
同时,本项目采用了新光源LED灯(发光二极管,lighting emitting diode,简称LED)。
与目前传统光源(白炽灯、日光灯、高压钠灯)相比,拥有光源纯、波长类型多、节能环保、使用寿命长、发热少和易于控制等优点,更有利于节约能源。
同时我们设计的植物智能补光系统可以根据不同植物在不同生长阶段的需光量不同,进行精准化定量补光,从而能以最少的能耗使植物处于最佳生长状态。
本项目以LED植物智能补光系统为研究对象,通过科学的研究与分析,最终做成一个基于单片机的LED植物智能补光系统的模拟机。
在此系统工作前预先设定好该时期植物生长所需的温度、红蓝光照度阀值,温度传感器对温室内温度进行检测,当温度高于促进光合作用的温度阀值时,再分别对红、蓝光照度进行检测,实际光照度在阀值以内时,系统可以自动对补光状态,根据所设阈值与实际值之差计算实际需光量,进而再根据与实际需光量对应的两路PWM 控制信号的占空比,分别产生对应的PWM 信号,达到控制LED 灯组的亮度对植物实施精确补光的目的。
从而保证植物一直处于最佳生长状态。
2 系统硬软件设计2.1系统整体结构整个系统由五个模块组成,分别是控制模块、检测模块、电源模块、补光模块和用户交换模块组成。
msp430 实验报告
msp430 实验报告MSP430 实验报告引言:MSP430是一款低功耗、高性能的微控制器,广泛应用于嵌入式系统开发领域。
本实验报告将介绍我对MSP430进行的一系列实验,包括基本的GPIO控制、定时器应用、模拟信号采集和通信接口应用等。
实验一:GPIO控制在本实验中,我使用MSP430的GPIO引脚控制LED灯的亮灭。
通过配置引脚的输入/输出模式以及设置引脚电平,我成功地实现了对LED灯的控制。
这为后续实验奠定了基础,也让我更加熟悉了MSP430的寄存器配置。
实验二:定时器应用在本实验中,我探索了MSP430的定时器功能。
通过配置定时器的时钟源和计数模式,我实现了定时器中断功能,并利用定时器中断实现了LED灯的闪烁。
这个实验让我更加深入地了解了MSP430的定时器模块,并学会了如何利用定时器进行时间控制。
实验三:模拟信号采集在本实验中,我使用MSP430的模拟信号输入引脚和模数转换模块,成功地将外部的模拟信号转换为数字信号。
通过配置ADC模块的采样速率和精度,我实现了对模拟信号的准确采集,并将采集到的数据通过串口输出。
这个实验让我对MSP430的模拟信号处理有了更深入的了解。
实验四:通信接口应用在本实验中,我使用MSP430的串口通信模块,实现了与外部设备的数据传输。
通过配置串口的波特率和数据格式,我成功地实现了与计算机的串口通信,并通过串口发送和接收数据。
这个实验让我掌握了MSP430与外部设备进行数据交互的方法。
结论:通过一系列的实验,我对MSP430的基本功能和应用有了更深入的了解。
MSP430作为一款低功耗、高性能的微控制器,具备丰富的外设和强大的处理能力,适用于各种嵌入式系统的开发。
通过学习和实践,我掌握了MSP430的GPIO控制、定时器应用、模拟信号采集和通信接口应用等基本技能,为以后的嵌入式系统开发打下了坚实的基础。
未来展望:MSP430作为一款成熟的微控制器,具备广阔的应用前景。
MSP430单片机系统时钟选择实验-改变LED灯闪烁频
MSP430单片机实践篇---MSP430单片机系统时钟选择实验-改变LED灯闪烁频率
一、学习要点:在上一节基础上改变MSP430单片机系统时钟,观察LED灯的闪烁频率。
#include<msp430x13x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;//停止看门狗
P1DIR |= 0x20;//设P1.5为输出口
/ห้องสมุดไป่ตู้ BCSCTL1= 0x80;//分频电阻选择为0(此时闪烁频率较慢)
// BCSCTL1= 0x87;//分频电阻选择为7(此时闪烁频率较快)
//
//
//硬件电路:MSP430F135核心实验板-I型
//硬件连接:
//
//调试器:MSP430FET全系列JTAG仿真器
//调试软件:IAR Embedded Workbench Version:3.41A编译
//******************************************************************************
(2)将如下程序拷贝粘贴到main.c文件中。
//*******************************************************************************
// D13x Demo -在上一节基础上改变系统时钟,观察LED灯的闪烁频率
msp430按键控制
第三讲按键控制一、概述LAUNCH PAD的实验板上共有两个按键,一个按键接至RESET脚,固定作为复位按键来使用(S1)。
按键S2连接在引脚P1.3,可供我们自由使用。
这里我们实现通过此按键控制LED的闪烁。
应当注意,连接按键的引脚松开时为高电平,按下为低电平。
按键一般可以通过扫描和中断来实现。
扫描是指程序通过循环不停地读取IO口的输入值,并以此判断按键是否按下。
中断实现可以免除扫描的麻烦,在按键按下时,中断当前的程序,执行中断处理函数,效率较高。
二、中断简介中断对于初学者来说,是最不容易理解的。
但它的道理实际上很简单,中断条件满足时,暂停正在运行的程序,开始处理中断服务函数,中断服务函数结束后返回,继续从之前停下的地方运行。
就好像是你原来在网上聊天,突然电话响了,接完电话继续上网一样。
这里,上网就像是初始运行的程序,电话响了是中断触发条件,接电话是中断服务程序。
只是设置好中断处理函数以后,每次中断运行的程序都是相同的。
每种CPU之中,都会有许多不同种类的中断。
对于单片机来说,最常用的中断有外部中断、定时器中断等。
而这些中断中,又有不同的优先级,有时还可以实现中断嵌套。
中断优先级是指系统中多个中断源可能同时提出中断请求,需要按中断的轻重缓急给每个中断源指定一个优先级别。
从头文件中,我们可以看到msp430g2553的中断优先级。
如图,最下面的复位中断具有最高优先级。
中断嵌套是指系统为某个中断请求服务时,可能再次接收到其他中断请求信号,这时系统有可能会再次中断,转去处理新的、优先级更高的中断请求。
对于msp430,一般情况下不允许任何中断嵌套,但是,若在中断中打开总中断,则不论优先级高低都会进行中断嵌套。
我们使用在按键这里的中断,被称为外部中断,意思是触发条件是来自外部的。
在程序中,要配置好中断,要考虑到很多方面。
首先,要确定是哪种中断,如外部中断就要配置IO 口的寄存器;其次,编写中断处理函数;最后,也是最重要的部分,打开总中断。
MSP430 LED扫描程序范例(采用HC595芯片扩展)(附原理图)
#i nclude <MSP430x14x.h>#i nclude "led.h"unsigned char seg[]={0x3f,0x06,0x5b,0x4f, /* 0 1 2 3*/0x66,0x6d,0x7d,0x07, /* 4 5 6 7 */0x7f,0x6f,0x77,0x7c, /* 8 9 A B */0x39,0x5e,0x79,0x71 /* C D E F */};void Init_Port(void){//将P1口所有的管脚在初始化的时候设置为输入方式P1DIR = 0;//将P1口所有的管脚设置为一般I/O口P1SEL = 0;// 将P1.0 P1.1 P1.2 设置为输出方向P1DIR |= BIT0;P1DIR |= BIT1;P1DIR |= BIT2;return;}void SHCLK_Hi(void){//P1.2管脚输出高电平P1OUT |= BIT2;return;}void SHCLK_Lo(void){//P1.2管脚输出低电平P1OUT &= ~(BIT2);return;}void STCLK_Hi(void){//P1.1管脚输出高电平P1OUT |= BIT1;return;}void STCLK_Lo(void){//P1.1管脚输出低电平P1OUT &= ~(BIT1);return;}void DataOut(unsigned char nV alue){int i;int j;for(i = 0;i < 8;i++){if ((nV alue & 0x01) == 1){P1OUT |= BIT0;//输出高电平}else{P1OUT &= ~(BIT0);//输出低电平}SHCLK_Hi();//时钟高电平,上升沿有效for(j = 10; j > 0; j--) ;//延迟一点时间SHCLK_Lo();//时钟低电平for(j = 10; j > 0; j--) ;nV alue >>= 1;}return;}void main(void){unsigned char nV alue;//初始化时钟Init_CLK();//端口初始化Init_Port();//清除锁存信号STCLK_Lo();//输出0nV alue = 0;DataOut(seg[nV alue]);//输出2nV alue = 2;DataOut(seg[nV alue]);//给锁存信号,显示上面的两位数据STCLK_Hi();return;}void Init_CLK(void){unsigned int i;BCSCTL1 = 0X00; //将寄存器的内容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1do{IFG1 &= ~OFIFG; // 清除OSCFault标志for (i = 0x20; i > 0; i--);}while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1BCSCTL2 = 0X00; //将寄存器的内容清零BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1 BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1 }。
基于MSP430G2553的按键测试程序
基于msp430G2系列的按键测试程序本程序有扫描和中断两种方式,代码均附后。
4、4×1独立按键实验(1)4×1键盘1:扫描数码管显示(2)4×1键盘2:xx数码管显示(3)4×1键盘3:控制LED(4)4×1键盘4:控制蜂鸣器5、4×4矩阵键盘实验(1)4×4键盘1:行列扫描数码管显示(2)4×4键盘2:行列扫描1602液晶显示3)4×4键盘3:控制LED蜂鸣器#include <msp430g2452.h>#defineBUTTONBIT3#defineLED_REDBIT0#defineLED_GREENBIT6#defineLED_DIRP1DIR#defineBUTTON_DIRP1DIR#defineBUTTON_OUTP1OUT#defineLED_OUTP1OUT#defineBUTTON_RENP1REN#defineBUTTON_ON(P1IN&BIT3)#defineBUTTON_OFF!(P1IN&BIT3)#defineLED_RED_ON()P1OUT|=BIT0#defineLED_RED_OFF()P1OUT&=~BIT0#defineLED_GREEN_ON()P1OUT|=BIT6#defineLED_GREEN_OFF()P1OUT&=~BIT6 volatile unsigned char i=0,flag=0;void main(void){WDTCTL = WDTPW + WDTHOLD; BUTTON_DIR &= ~BUTTON;LED_DIR|= LED_RED+LED_GREEN;BUTTON_REN |= BUTTON;BUTTON_OUT= BUTTON;while(1){/*通过按键改变选择标志位*/if(BUTTON_OFF){flag=!flag;while(BUTTON_OFF);}if(flag){LED_RED_ON();i=10;while(i--)_delay_cycles(500);LED_RED_OFF();LED_GREEN_ON();i=10;while(i--)_delay_cycles(500);LED_GREEN_OFF();}else{LED_OUT |= LED_RED+LED_GREEN;i=10;while(i--)_delay_cycles(500);LED_OUT ^= (LED_RED+LED_GREEN);i=10;while(i--)_delay_cycles(500);}}}/**************该版本编译后的代码与第一个版本是一致的,请看差别在哪儿************/#include <msp430g2452.h>#defineBUTTONBIT3#defineLED_REDBIT0#defineLED_GREENBIT6#defineLED_DIRP1DIR#defineBUTTON_DIRP1DIR#defineBUTTON_OUTP1OUT#defineLED_OUTP1OUT#defineBUTTON_RENP1REN#defineBUTTON_ON(P1IN&BIT3)#defineBUTTON_OFF!(P1IN&BIT3)#defineBIT_SET(x , y)x |= (y)#defineBIT_CLR(x , y)x &=~(y)volatile unsigned char i=0,flag=1;void main(void){WDTCTL = WDTPW + WDTHOLD;BIT_CLR(BUTTON_DIR , BUTTON);BIT_SET(LED_DIR , LED_RED+LED_GREEN);BIT_SET(BUTTON_REN , BUTTON);BIT_SET(BUTTON_OUT , BUTTON);/********************************************************/while(1){/*通过按键改变选择标志位*/if(BUTTON_OFF){flag=!flag;while(BUTTON_OFF);}/*********************************************** ******/if(flag){BIT_SET(LED_OUT , LED_RED);i=10;while(i--)_delay_cycles(500);BIT_CLR(LED_OUT , LED_RED);/*****************************************************/BIT_SET(LED_OUT , LED_GREEN);i=10;while(i--)_delay_cycles(500);BIT_CLR(LED_OUT ,LED_GREEN);}/*****************************************************/ else{BIT_SET(LED_OUT ,LED_RED+LED_GREEN);i=10;while(i--)_delay_cycles(500);/*****************************************************/BIT_CLR(LED_OUT , LED_RED+LED_GREEN);}}}i=10;while(i--)_delay_cycles(500);。
proteus的msp430仿真,一学就会
第一步:在IAR中编写430程序:
为了便于实现和理解,我的例子比较简单,程序将P3OUT中的数据传给P2IN,然后再把P2IN 中的数据给P1OUT,最后输出到LED灯,程序如下:
#include <msp430x14x.h>
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
P3DIR = 0xff; //P3设置为输出,P2设置为输入,P1设置为输出
P2DIR = 0x00;
P1DIR = 0xff;
P3OUT = 0x4a; //P3输出灯的控制信息,并通过连线传给P2IN
P1OUT = P2IN; //P2将信息给P1
while(1);
}
第二步:将程序生成为hex文件
右键TEST2,如图1,点击Option
图1
选中左边栏中的Linker,然后点击右栏中的output,如图2
图2
勾中Output file下的”Override default”选项并将输出文件名后辍改为”.hex”.在Format选项框中选中Other, Output 后选择”inter-extended”。
其他的值保持默认,点击确定。
点击”make”,生成proteus中需要的“.hex”文件,该文件生成在Debug文件夹下的Exe 中,如图3
图3
第三步:proteus中搭建好电路
图4
第四步:双击单片机导入生成的.hex程序,运行,就得到所要的结果
图5。
用按键控制ED灯的亮灭
用按键控制LED灯的亮灭,当按键按下时,LED灯亮,当按键松开时,LED灯灭。
#include"msp430f6638.h"unsigned char flag;void main(void){WDTCTL = WDTPW+WDTHOLD; // Stop WDTP4DIR &=~(BIT2);P4DIR |= BIT4+BIT5+BIT6; // P4.4,P4.5,P4.6 set as outputP4OUT &=~(BIT4+BIT5+BIT6); // set led offP2IE |= BIT6; // enable P2.6 interruptP2IFG &= ~(BIT6); // clean interrupt flag__enable_interrupt(); // enable interruptwhile(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 onP2IFG &=~BIT6; // clean interrupt flag}用按键控制LED灯的亮灭,当按键按下时,LED灯亮,当按键松开时,LED灯灭。
(查询)#include"msp430f6638.h"void main(void){WDTCTL = WDTPW+WDTHOLD; // Stop WDT//setting directionP4DIR &= ~(BIT2); //setting IO for inputP4DIR |= BIT4+BIT5+BIT6; // P4.4,P4.5,P4.6 set as outputwhile (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<msp430f6638.h>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输出。
MSP430按键输入和led点阵显示解读
第4章键盘和显示器的应用在单片机应用系统中,键盘和显示器是非常重要的人机接口。
人机接口是指人与计算机系统进行信息交互的接口,包括信息的输入和输出。
常用输入设备主要是键盘,常用输出设备包括发光二极管、数码管和液晶显示器等。
4.1 键盘输入键盘用于实现单片机应用系统中的数据信息和控制命令的输入,按结构可分为编码键盘和非编码键盘。
编码键盘上闭合键的识别由专用的硬件编码器实现,并产生相应的键码值,如计算机键盘。
非编码键盘是通过软件的方法产生键码,不需要专用的硬件电路。
为了减少电路的复杂程度,节省单片机的I/O口,在单片机应用系统中广泛使用非编码键盘,主要对象是各种按键或开关。
这些按键或开关可以独立使用(称之为独立键盘),也可以组合使用(称之为矩阵式键盘)。
4.1.1 按键电路与按键抖动处理按键电路连接方法非常简单,如图4.1所示。
此电路用于通过外力使按键瞬时接通开关的场合,如单片机的RESET电路中,通过按键产生一个瞬时的低电压,CPU感知这个低电压后重启。
图4.1 按键复位电路由于按键的闭合与断开都是利用其机械弹性实现的,当机械触点断开、闭合时,会产生抖动,这种抖动操作用户感觉不到,但对CPU来说,其输出波形则明显发生变化,如图4.2所示。
图4.2 按键开、闭时的电压抖动波形按键按下和释放时的抖动时间一般为10~20ms ,按键的稳定闭合期由操作用户的按键动作决定,一般为几百毫秒到几秒,而单片机CPU的处理速度在微秒极,因此,按键的一次闭合,有可能导致CPU的多次响应。
为了避免这种错误操作,必须对按键电路进行去抖动处理。
常用的去抖动方法有硬件方式和软件方式两种。
使用硬件去抖动的方式,需要在按键连接的硬件设计上增加硬件去抖电路,比如将按键输出信号经过R-S 触发器或 RC 积分电路后再送入单片机,就可以保证按一次键只发出一个脉冲。
软件方式去抖动的基本原理是在软件中采用时间延迟,对按键进行两次测试确认,即在第一次检测到按键按下后,间隔 10ms 左右,再次检测该按键是否按下,只有在两次都测到按键按下时才最终确认有键按下,这样就可以避开抖动时间段,消除抖动影响。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按键篇经过一短时间的学习,下面,亲自动手编写一下程序吧。
程序的目的是:按下按键,控制LED的亮和灭。
短按键,则小灯亮1秒,然后灭;长按键,小灯常亮。
首先,完成键盘的扫描程序。
第一点:如果是扫描,就要用到定时器。
我想设计定时器每隔10ms扫描一次按键。
定时器,我选用定时器A。
它的定时中断函数如下:函数名称:TimerA_ISR功能:定时器A的中断服务函数参数:无返回值:无********************************************/#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){GetKey();}上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用GetKey()函数一次。
GetKey()函数就是扫描键盘按键的函数了。
在GetKey()函数中,会根据按键类型(长按/短按)返回不同的数值。
根据返回的数值,做小灯亮法的操作。
那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量ucharFlagLcd ; 来保存返回值。
这个变量在全局变量中定义,以保证它的作用域。
那么定时函数就变为#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey();}定时器中断的时间间隔,我在主函数中定义。
这样写:CCTL0 = CCIE; //使能CCR0中断CCR0 = 40; //设定周期0.01STACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK,增计数模式这样,定时器这块就算完工了。
那么,下面进行按键扫描程序。
按键的定义是这样的,根据我板子的按键原理图如下这是一个矩阵键盘。
其中KEY就是外部高电平3.3V。
我只想用其中的P1.0作为这次试验的按键。
那么,做些设置就可以了。
将P1.7方向设置为输出,并输出电平为低。
这样,才能实现当K1按下时,P1.0输入为低;当K1抬起时,P1.0输入为高的效果。
对P1口进行初始化:void Init_Keypad(void){P1DIR = 0xfe; //P1.0设置为输入状态, P1.1~P1.7设置为输出状态P1OUT &= 0x7f; // P1.0~P1.6输出高电平,P1.7输出低电平}下面是键盘扫描函数:unsigned char GetKey(){unsigned char keyRetu=0; //返回的按键值static unsigned char s_keyState=0,keyTime=0; //按键状态,按键按下的时间计数器switch (s_keyState){case 0:if((P1IN&0x01)==0) //检测到有按键,转到状态1,相当于是消抖过程。
((P1IN&0x01)==0判断P1.0口输入是高还是低电平{s_keyState=1;}break;case 1:if((P1IN&0x01)==0) //再次检测到有按键,转到状态2{s_keyState=2;keyTime=0; //清零按键时间计数器}else{s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0}break;case 2:if((P1IN&0x01)==1) //检测到按键松开{s_keyState=0; //状态转到状态0keyRetu=1; //输出1}else{if(++keyTime>=50) //按下时间>1s{s_keyState=3; //转到状态3keyTime=0; //清零按键时间计数器keyRetu=2; // 输出2}}break;case 3:if((P1IN&0x01)==1) //检测到按键松开{s_keyState=0; //状态转到状态0}else{s_keyState=3; //转到状态3}break;}return keyRetu;}上面这个扫描函数,根据按键K1是长按还是短按,返回不同的值:长按,返回2;短按,返回1。
获得了返回值以后,就要对LED进行操作了。
我的板子的LED如下图LED是LED供电高电平,这里我只想用其中的D1作为实验灯。
初始化P2.0口:P2DIR = 0xff; //设置P2口方向为输出P2OUT = 0xff; //设置P2口输出高电平那么P2OUT = 0xfe,则LED亮;P2OUT = 0xff,则LED灭。
这个很好实现。
但是,怎么样才能持续亮1s呢?这个问题还需要定时器来解决。
我在这里还利用定时器A来完成这个任务。
在主程序中定义全局变量unsigned int TIME_1_S=0;然后再定时器中断函数中做些改动#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey();If(FlagLcd==1)TIME_1_S=1;If((TIME_1_S>0)&&( TIME_1_S<100))TIME_1_S++;ElseTIME_1_S=0;}这样,在控制LED的时候,可以这样写If(TIME_1_S>0)P2OUT = 0xfe;ElseP2OUT = 0xff;就实现了亮1S的效果。
那么长按键的时候呢,则需要再做一下处理。
在主程序中定义全局变量unsigned int TIME_L_S=0;然后再定时器中断函数中做些改动#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey();If(FlagLcd==1)TIME_1_S=1;If((TIME_1_S>0)&&( TIME_1_S<100))TIME_1_S++;ElseTIME_1_S=0;If(FlagLcd==2)TIME_L_S=1;}If((TIME_1_S>0)||( TIME_L_S==1))P2OUT = 0xfe;ElseP2OUT = 0xff;到这里,基本的实现函数都已经完成了。
剩下的事情,就是把相关框架搭建一下了第一:是main.c文件#include <msp430x14x.h>#include "key.h"unsigned char FlagLcd ;unsigned int TIME_L_S=0;unsigned int TIME_1_S=0;void main(void){P1DIR = 0XFF;P1OUT = 0XFF;P2DIR = 0XFF;P2OUT = 0XFF;P3DIR = 0XFF;P3OUT = 0XFF;P4DIR = 0XFF;P4OUT = 0XFF;P5DIR = 0XFF;P5OUT = 0XFF;P6DIR = 0XFF;P6OUT = 0XFF;WDTCTL = WDTPW + WDTHOLD; //关闭看门狗P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换CCTL0 = CCIE; //使能CCR0中断CCR0 = 40; //设定周期0.01STACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK,增计数模式P2DIR = 0xff; //设置P2口方向为输出P2OUT = 0xff; //设置P2口输出高电平Init_Keypad();_EINT();//使能全局中断while(1){if((TIME_1_S>0)||( TIME_L_S==1))P2OUT = 0xfe;elseP2OUT = 0xff;}}#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey();if(FlagLcd==1)TIME_1_S=1;if((TIME_1_S>0)&&( TIME_1_S<100))TIME_1_S++;elseTIME_1_S=0;if(FlagLcd==2)TIME_L_S=1;}第二:key.c文件#include <msp430x14x.h>void Init_Keypad(void){P1DIR = 0xfe; //P1.0设置为输入状态, P1.1~P1.7设置为输出状态P1OUT &= 0x7f; // P1.1~P1.7输出高电平}unsigned char GetKey(){unsigned char keyRetu=0; //返回的按键值static unsigned char s_keyState=0,keyTime=0; //按键状态,按键按下的时间计数器switch (s_keyState){case 0:if((P1IN&0x01)==0) //检测到有按键,转到状态1,相当于是消抖过程{s_keyState=1;}break;case 1:if((P1IN&0x01)==0) //再次检测到有按键,转到状态2{s_keyState=2;keyTime=0; //清零按键时间计数器}else{s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0}break;case 2:if((P1IN&0x01)==1) //检测到按键松开{s_keyState=0; //状态转到状态0keyRetu=1; //输出1}else{if(++keyTime>=50) //按下时间>1s{s_keyState=3; //转到状态3keyTime=0; //清零按键时间计数器keyRetu=2; // 输出2}}break;case 3:if((P1IN&0x01)==1) //检测到按键松开{s_keyState=0; //状态转到状态0}else{s_keyState=3; //转到状态3}break;}return keyRetu;}第三:key.h文件void Init_Keypad(void);unsigned char GetKey();。