msp430按键控制LED最基本程序

合集下载

430单片机点亮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触摸按键程序

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灯实验原理

主题:单片机独立按键控制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等,不同的单片机板具有不同的特性和使用方法,因此需要根据实验要求来选择适合的单片机板。

msp430-流水灯

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灯亮灭程序编写

使用按键控制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文件并仿真

msp430 按键控制LED 最基本程序

msp430 按键控制LED 最基本程序

按键篇经过一短时间的学习,下面,亲自动手编写一下程序吧。

程序的目的是:按下按键,控制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作为这次试验的按键。

msp430Led按键控制灯亮程序

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单片机入门例程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 实验报告

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单片机系统时钟选择实验-改变LED灯闪烁频
选择外部8m高频晶振作为mclk此时闪烁频率较快unsignedint循环do3按照iarmsp430项目编译与jtag仿真调试所讲述方法进行项目编译与jtag调试运行即可看到程序运行效果
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按键控制

msp430按键控制

第三讲按键控制一、概述LAUNCH PAD的实验板上共有两个按键,一个按键接至RESET脚,固定作为复位按键来使用(S1)。

按键S2连接在引脚P1.3,可供我们自由使用。

这里我们实现通过此按键控制LED的闪烁。

应当注意,连接按键的引脚松开时为高电平,按下为低电平。

按键一般可以通过扫描和中断来实现。

扫描是指程序通过循环不停地读取IO口的输入值,并以此判断按键是否按下。

中断实现可以免除扫描的麻烦,在按键按下时,中断当前的程序,执行中断处理函数,效率较高。

二、中断简介中断对于初学者来说,是最不容易理解的。

但它的道理实际上很简单,中断条件满足时,暂停正在运行的程序,开始处理中断服务函数,中断服务函数结束后返回,继续从之前停下的地方运行。

就好像是你原来在网上聊天,突然电话响了,接完电话继续上网一样。

这里,上网就像是初始运行的程序,电话响了是中断触发条件,接电话是中断服务程序。

只是设置好中断处理函数以后,每次中断运行的程序都是相同的。

每种CPU之中,都会有许多不同种类的中断。

对于单片机来说,最常用的中断有外部中断、定时器中断等。

而这些中断中,又有不同的优先级,有时还可以实现中断嵌套。

中断优先级是指系统中多个中断源可能同时提出中断请求,需要按中断的轻重缓急给每个中断源指定一个优先级别。

从头文件中,我们可以看到msp430g2553的中断优先级。

如图,最下面的复位中断具有最高优先级。

中断嵌套是指系统为某个中断请求服务时,可能再次接收到其他中断请求信号,这时系统有可能会再次中断,转去处理新的、优先级更高的中断请求。

对于msp430,一般情况下不允许任何中断嵌套,但是,若在中断中打开总中断,则不论优先级高低都会进行中断嵌套。

我们使用在按键这里的中断,被称为外部中断,意思是触发条件是来自外部的。

在程序中,要配置好中断,要考虑到很多方面。

首先,要确定是哪种中断,如外部中断就要配置IO 口的寄存器;其次,编写中断处理函数;最后,也是最重要的部分,打开总中断。

基于MSP430的新型LED调光系统

基于MSP430的新型LED调光系统

Z HA N G J u n j i , S HE N Y a n x i a
( I n s t i t u t e o f E l e c t r i c a l Au t o m a t i o n , J i a n g n a n U n i v e r s i t y , Wu x i 2 1 4 1 2 2 , C h i n a )
第1 3卷 第 1期 2 0 1 4年 2月
江 南 大 学 学 报 (自 然 科 学 版 ) J o u r n a l o f J i a n g n a n Un i v e r s i t y ( Na t u r a l S c i e n c e Ed i t i o n )
采 用单 端反 激 式 开 关 电 源 拓 扑 结 构 , 采 用 MA X1 6 8 2 2作 为 L E D的恒 流驱动 器。 调 光部分 采 用 MS P 4 3 0 F 1 4 9单 片机 作 为控 制核 心 , 利 用定 时 器的精 确定 时来 产 生 占空比 可调 的 P WM 信 号对 L E D
Ab s t r a c t : A L E D w i r e l e s s d i mmi n g s y s t e m b a s e d o n t h e MS P 4 3 0 i s d e s i g n e d i n t h i s p a p e r . I n t h e d r i v e p o w e r , t h e
M S P 4 3 0 F 1 4 9 i s u s e d a s t h e c e n t e r c o n t r o l l e r . T h e e x a c t t i m i n g o f t h e t i me r i s g e n e r a t e d b y u s i n g a n a d j u s t a b l e P WM

MSP430 LED扫描程序范例(采用HC595芯片扩展)(附原理图)

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 }。

汇编按键控制led灯亮灭编写程序 概述

汇编按键控制led灯亮灭编写程序 概述

汇编按键控制led灯亮灭编写程序概述1. 引言1.1 概述本文旨在介绍使用汇编语言编写程序,以实现按键控制LED灯亮灭的功能。

通过该实验,我们可以深入了解汇编语言的基本原理和操作方法,并学会将其应用于具体的电路控制中。

1.2 文章结构本文主要分为四个部分,分别是引言、汇编按键控制LED灯亮灭编写程序、程序测试与调试过程及结果分析以及总结和展望。

在引言部分,我们将简要介绍文章的背景和目的,为读者提供整个实验的概览。

接下来的部分将逐步介绍硬件准备工作、程序设计思路、关键代码解读与实现步骤等内容。

随后,我们将介绍测试环境搭建、测试过程记录以及结果分析与优化方案等内容。

最后,在总结和展望部分,我们将对整个实验进行总结,并提出改进方向和未来发展方向。

1.3 目的本文的目的是帮助读者了解如何使用汇编语言编写按键控制LED灯亮灭的程序,通过这一示例项目引导读者熟悉汇编语言的基础知识,并培养其分析和解决问题的能力。

通过实验过程,读者可以了解硬件准备工作、程序设计思路以及测试调试过程,并能够根据实际需求进行结果分析和优化方案的提出。

此外,本文还展望了未来发展方向,希望读者能够在此基础上进一步探索和应用汇编语言的相关知识。

以上是文章“1. 引言”部分的内容,旨在概述本文的背景、结构和目的。

如果需要更加详细的内容,请继续阅读后续章节。

2. 汇编按键控制LED灯亮灭编写程序:2.1 完成硬件准备工作:在开始编写汇编程序之前,首先需要进行硬件准备工作。

我们将使用一个单片机来控制LED灯的亮灭,并通过按键来触发控制操作。

为此,我们需要将LED与单片机的输出引脚连接,并将按键与单片机的输入引脚连接。

确保电路连接正确无误后,我们可以开始进行程序设计。

2.2 程序设计思路:在本部分中,我们将介绍如何使用汇编语言设计一个按键控制LED灯亮灭的程序。

该程序的基本原理是通过检测按键状态来改变LED的亮度状态,即当按键被按下时,LED亮起;当按键未被按下时,LED熄灭。

proteus的msp430仿真,一学就会

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灯的亮灭

用按键控制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输出。

430学习程序.

430学习程序.

1. LED 流水灯 ................................................... 1 2 4*4矩阵键盘扫描实验 ................................ 1 3 1602字符型液晶显示实验 .......................... 2 4 LCD128*64打点及采样波形 ...................... 4 5 DS1302实时时钟实验 ................................. 8 6 ADC12电压测量实验 .. (12)1. LED 流水灯#include "msp430x14x.h" #define uint unsigned int #define uchar unsigned char uchar LedData=0x80; //延时子程序void DelayMs(uint ms){ while(ms--){for(uint i=0;i<800;i++); } }//时钟初始化函数 void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启 LFXT1工作在低频模式 ACLK 不分频 最高的标称频率 DCOCTL=DCO2+DCO1+DCO0;//DCO 为最高频率 do{IFG1&=~OFIFG;//清除振荡器失效标志 for(uint i=255;i>0;i--); }while(IFG1&OFIFG); //判断XT2是否起振 BCSCTL2=SELM1+SELS;//MCLK SMCLK 时钟源为TX2CLK 不分频}void main(){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗 InitClock(); _DINT();//关闭中断P2SEL=0x00;//P2口所有引脚设置为一般的IO 口 P2DIR=0xFF;//P2口所有引脚设置为输出方向 while(1){//LedData>>=1;//右移一位 //if(LedData==0) LedData=0x80; P2OUT=LedData;//P2口输出数据 DelayMs(400); }}2 4*4矩阵键盘扫描实验功能:在数码管上显示输入的值#include "msp430x14x.h" #define uint unsigned int#define uchar unsigned char uchar KeyValue=0xFF; //共阳数码管编码表uchar Code[18]={0xC0,0xF9,0xA4,0xB0,//0,1,2,3 0x99,0x92,0x82,0xF8,//4,5,6,7 0x80,0x90,0x88,0x83,//8,9,A,b 0xC6,0xA1,0x86,0x8E,//C,d,E,F 0xBF,0xFF};//-,全灭uchar Bit[8]={16,16,16,16,16,16,16,16}; //数码管各位要显示的数字 //键值编码表uchar KeyCode[16]={0x77,0x7B,0x7D,0x7E,//0,1,2,3 0xB7,0xBB,0xBD,0xBE,//4,5,6,7 0xD7,0xDB,0xDD,0xDE,//8,9,A,b 0xE7,0xEB,0xED,0xEE};//C,d,E,F uchar BitCode=0x80; //数码管位码初值 //时钟初始化函数 void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启 LFXT1工作在低频模式 ACLK 不分频 最高的标称频率 DCOCTL=DCO2+DCO1+DCO0;// DCO 为最高频率 do{IFG1&=~OFIFG;//清除振荡器失效标志 for(uint i=255;i>0;i--); }while(IFG1&OFIFG);//判断XT2是否起振BCSCTL2=SELM1+SELS;//MCLK SMCLK 时钟源为TX2CLK 不分频 }//端口初始化函数 void InitPort(void){P1SEL=0x00;//P1口所有引脚设置为一般的IO 口 P1DIR=0x0F;//P1.0 P1.1 P1.2 P1.3设置为输出方向 P1OUT=0x00;//P1口先输出低电平 P1IE=0xF0;//P1.4 P1.5 P1.6 P1.7中断允许 P1IES=0xF0;//P1.4 P1.5 P1.6 P1.7下降沿触发中断 P2SEL=0x00;//P2口所有引脚设置为一般的IO 口 P4SEL=0x00;//P4口所有引脚设置为一般的IO 口P2DIR=0xFF;//P2口所有引脚设置为输出方向 P4DIR=0xFF;//P4口所有引脚设置为输出方向 P2OUT=0x00;//P2口先输出低电平 P4OUT=0xFF;//P4口先输出低电平 P5SEL&=~BIT7;//P5.7设置为一般的IO 口 P5DIR|=BIT7;//P5.7设置为输出方向 P5OUT&=~BIT7;//P5.7输出低电平来使能74HC573来驱动数码管 }//延时子函数 void Delay(void){ for(uchar i=255;i>0;i--); }//按键分析程序 void KeyProcess(void){ uchar OutData=0x07;for(uchar i=0;i<4;i++){//扫描4列 OutData|=0xF0; P1OUT=OutData;if(P1IN!=OutData) KeyValue=P1IN; OutData>>=1; }P1OUT=0x00;//恢复原来的值 }//端口1中断处理程序#pragma vector=PORT1_VECTOR __interrupt void Port1INT(void){ Delay(); KeyProcess();P1IFG=0x00;//清除中断标志位 }//延时子程序void DelayMs(uint ms){ while(ms--){for(uint i=0;i<800;i++); } }//数码管扫描显示程序 void Display(void){for(uchar i=0;i<16;i++){//查找键值对应的数字 if(KeyValue==KeyCode[i]){Bit[0]=Bit[1]=Bit[2]=Bit[3]=Bit[4]=Bit[5]=Bit[6]=Bit[7]=i;//显示键值对应的数字break;}}for(uchar i=0;i<8;i++){ P4OUT=BitCode; //输出位码 P2OUT=Code[Bit[i]]; //输出段码 BitCode>>=1;//位码右移一位 if(BitCode==0) BitCode=0x80; DelayMs(1); //延时1msP2OUT=0xFF; } }void main(){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗 InitClock(); InitPort();_EINT();//打开中断 while(1){ Display(); } }3 1602字符型液晶显示实验功能:在第一行显示 Model:WJ89S52 在第二行显示 #include "msp430x14x.h" #define uchar unsigned char #define uint unsigned int#define RS_HIGH P4OUT|=BIT0 //指令数据选择信号 #define RS_LOW P4OUT&=~BIT0 #define RW_HIGH P4OUT|=BIT1 //读写信号 #define RW_LOW P4OUT&=~BIT1 #define E_HIGH P4OUT|=BIT2 //使能信号 #define E_LOW P4OUT&=~BIT2 #define BUSY_OUT P2DIR|=BIT7 #define BUSY_IN P2DIR&=~BIT7 #define BUSY_DA TA P2IN&BIT7 uchar Data1[16]="V1= v,V2= v"; uchar Data2[16]="V3=V1+V2= v";uint data1;uint data2;//延时子程序DelayMS(uint ms){uint i;while(ms--){for(i=0; i<800;i++);}}// 测试LCD忙碌状态void LcdBusy(){RS_LOW;RW_HIGH;E_HIGH;_NOP();_NOP();BUSY_IN;while(BUSY_DA TA);BUSY_OUT;E_LOW;}//写入指令到LCDWriteCommand(uchar Command){LcdBusy();RS_LOW;RW_LOW;E_HIGH;_NOP();_NOP();P2OUT=Command;_NOP();_NOP();E_LOW;}//写入字符数据到LCDWriteData(uchar Data){LcdBusy();RS_HIGH;RW_LOW;E_HIGH;_NOP();_NOP();P2OUT=Data;_NOP();_NOP();E_LOW;}//LCD初始化设定LcdInit(){WriteCommand(0x38);//8位数据端口,2行显示,5*7点阵DelayMS(5);WriteCommand(0x0F);//开启显示, 无光标DelayMS(5);WriteCommand(0x06);//AC递增, 画面不动DelayMS(5);WriteCommand(0x01);//清屏DelayMS(5);}//时钟初始化函数void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启LFXT1工作在低频模式ACLK不分频最高的标称频率DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率do{IFG1&=~OFIFG;//清除振荡器失效标志for(uint i=255;i>0;i--);}while(IFG1&OFIFG);//判断XT2是否起振BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK 不分频}//端口初始化函数void InitPort(void){P2SEL=0x00;//P2口所有引脚设置为一般的IO口P4SEL=0x00;//P4口所有引脚设置为一般的IO口P2DIR=0xFF;//P2口所有引脚设置为输出方向P4DIR=0xFF;//P4口所有引脚设置为输出方向}//主程序main(){uchar i;uint sum;InitClock();WDTCTL=WDTPW+WDTHOLD;//关闭看门狗InitPort();LcdInit();//Lcd初始化_DINT();//关闭中断data1=643;data2=789;sum=data1+data2;Data1[3]=data1/100+'0';Data1[4]=data1%100/10+'0';Data1[5]=data1%10+'0';Data1[11]=data2/100+'0';Data1[12]=data2%100/10+'0';Data1[13]=data2%10+'0';Data2[9]=sum/1000+'0';Data2[10]=sum%1000/100+'0';Data2[11]=sum%100/10+'0';Data2[12]=sum%10+'0';while(1){WriteCommand(0x80);//定位在第一行第一个位置for(i=0;i<16;i++) WriteData(Data1[i]); /*DelayMS(1000);*/WriteCommand(0x80|0x40);//定位在第二行第一个位置for(i=0;i<16;i++) WriteData(Data2[i]);};}4 LCD128*64打点及采样波形#include "msp430x16x.h"#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define CD_HIGH P4OUT|=BIT1;#define CD_LOW P4OUT&=~BIT1;#define E_HIGH P4OUT|=BIT2;#define E_LOW P4OUT&=~BIT2;#define WR_HIGH P4OUT|=BIT4;#define WR_LOW P4OUT&=~BIT4;#define RD_HIGH P4OUT|=BIT5;#define RD_LOW P4OUT&=~BIT5; // ASCII 字模宽度及高度定义,ASCII 字模显示为8*16#define ASC_CHR_WIDTH 8#define ASC_CHR_HEIGHT 16uchar gCurRow,gCurCol;// 当前行列存储行高16 点列宽8点uchar INCOM;//状态字char turnf[8] = {7,6,5,4,3,2,1,0};#define TRUE 1#define FALSE 0//延时子程序void DelayMs(uint ms){while(ms--){for(uint i=0;i<800;i++);}}void delay(void){uchar i;for(i = 0;i < 15;i++)_NOP();}//时钟初始化函数void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启LFXT1工作在低频模式ACLK不分频最高的标称频率DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率do{IFG1&=~OFIFG;//清除振荡器失效标志for(uint i=255;i>0;i--);}while(IFG1&OFIFG);//判断XT2是否起振BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK 不分频}//端口初始化函数void InitPort(){P1SEL=0x00;//P1口所有引脚设置为一般的IO口P1DIR=0x00;//P1.2 P1.3 P1.4 P1.5 P1.6 P1.7设置为输出方向P1OUT=0xff;//P1口先输出高电平P1IE=0xFF;//P1.0 P1.1中断允许P1IES=0xFF;//P1.0 P1.1下降沿触发中断P2SEL=0x00;//P2口所有引脚设置为一般的IO口P4SEL=0x00;//P4口所有引脚设置为一般的IO口P2DIR=0xFF;//P2口所有引脚设置为输出方向P4DIR=0xFF;//P4口所有引脚设置为输出方向P2OUT=0x00;//P2口先输出低电平P4OUT=0xFF;//P4口先输出高电平P5DIR=0xFF;//P5口所有引脚设置为输出方向P5OUT=0x00;//P5口先输出低电平P3DIR=0xff;}/************************************************//* 读状态字*//************************************************/ void Lcdsta(){E_HIGH;P2DIR=0x00;CD_HIGH;RD_LOW;WR_HIGH;INCOM=P2IN;E_LOW;P2DIR=0xff;}/************************************************//* 状态位STA1,STA0判断读写指令和读写数据*//* 在读写数据或者写入命令前必须保证均为1 *//************************************************/ void STA01(){uchar i;for(i=10;i>0;i--){if((INCOM&0x03)==0x03) // 读取状态{break;}}}/********************************************//* 检查STA2,如果STA2=1 为自动读状态*//*****************************************/void STA2(){unsigned char i;for(i=10;i>0;i--){if((INCOM&0x04)==0x04){break;}}}/***********************************************/ /* 状态位STA3 判断STA3 = 1 数据自动写状态*//***********************************************/ void STA3(){unsigned char i;for(i=10;i>0;i--){if((INCOM&0x08)==0x08){break;}}}/************************************************/ /* 状态位STA6 判断STA6 =1 屏读/屏拷贝状态*//************************************************/ void STA6(){unsigned char i;for(i=10;i>0;i--){if((INCOM&0x40)==0x40){break;}}}/************************//* 写指令*//************************/void WriteCommand(uchar Command) {STA01();E_HIGH;CD_HIGH;WR_LOW;P2OUT=Command;E_LOW;}/************************//* 写数据*//************************/void fnPR13(uchar Data){STA01();E_HIGH;CD_LOW;WR_LOW;P2OUT=Data;E_LOW;}/************************//* 写双参数的指令*//************************/void fnPR1(char Cmd1,char Cmd2,char Dat) {fnPR13(Cmd1);fnPR13(Cmd2);WriteCommand(Dat);}/************************//* 写单参数的指令*//************************/void fnPR11(char Cmd,char Dat){fnPR13(Cmd);WriteCommand(Dat);}/************************//* 写无参数的指令*//************************/void fnPR12(char Dat){WriteCommand(Dat);}/************************************************//* 取当前行数据*/ // 当前行列存储行高16 点列宽8点/************************************************/uchar fnGetRow(){return(gCurRow);}/************************************************//* 取当前列数据*//************************************************/uchar fnGetCol(){return(gCurCol);}/************************//* 设置当前地址RAM里*//************************/void fnSetPos(char urow,char ucol){uint iPos;iPos = (int)urow * 30 + ucol; //图形、文本显示区宽度(30字节/行)fnPR1(iPos&0xFF,iPos/256,0x24);//地址指针位置(高字节iPos/256)?gCurRow = urow;gCurCol = ucol;}/**********************//* 设置当前显示行列*//**********************/void cursor(unsigned char uRow, unsigned char uCol){fnSetPos(uRow * 16, uCol);//文字显示,两个字节(两行——16)}/*********************/ /* 清屏 */ /*********************/ void cls() { int i;fnPR1(0x00,0x00,0x24); // 置地址指针为从零开始 fnPR12(0xB0); // 自动写for(i=0;i<240*128/8;i++) // 清一屏 {STA3();fnPR13(0x0); // 写数据实际使用时请将0x55 改成0x0 }fnPR12(0xB2); // 自动写结束fnPR1(0x00,0x00,0x24); // 重置地址指针 gCurRow = 0; // 置地址指针存储变量 gCurCol = 0; }/******************************/ /* 在col 行row 列显示内部字符dat*/ /******************************/ void printf(char col,char row,char dat) {uchar D1; D1=col*16+row; fnPR1(D1,0x00,0x24); // 置地址指针,d1代表从左至右第D1个字符(0~127),每个字符8*8点fnPR11(dat,0xc4);//地址不变,写数据,dat 为内部字符地址 }/************************/ /* LCD 初始化 */ /************************/ void fnLCMInit() {fnPR1(0x00,0x00,0x40); // 文本显示区首地址fnPR1(0x10,0x00,0x41); // 文本显示区宽度(30字节/行) fnPR1(0x00,0x00,0x42); // 图形显示区首地址fnPR1(0x1E,0x00,0x43); // 图形显示区宽度(30字节/行) fnPR12(0xA0|0x01); // 光标形状 fnPR12(0x80); // 显示方式设置 fnPR12(0x90|0x0c); // 显示开关设置 }/***********************************************/// 主函数/**********************************************/ void main(void) {int i,j;WDTCTL=WDTPW+WDTHOLD;//关闭看门狗 InitClock(); InitPort();fnLCMInit(); _DINT();//关闭中断 cls(); //cursor(0,0);for(i=0;i<8;i++) for(j=0;j<16;j++) printf(i,j,0x00); while(1) {printf(0,0,0x36);//V printf(0,1,0x41);//a printf(0,10,0x36);//V//电流显示printf(2,0,0x29);//I printf(2,1,0x41);//a printf(2,10,0x21);//Aprintf(3,0,0x29);//I printf(3,1,0x45);//e printf(3,10,0x21);//Aprintf(4,0,0x36);//V printf(4,1,0x4B);//k printf(4,10,0x36);//Vprintf(5,0,0x36);//V printf(5,1,0x5A);//z printf(5,10,0x36);//V}}5 DS1302实时时钟实验功能:在数码管上显示从DS1302读取的时间日期星期数据时间格式:时-分-秒日期格式:年月日-星期C键:选择显示时间还是日期D键:循环选择所要编辑的位E键:编辑的位的数值加1F键:编辑的位的数值减1#include "msp430x14x.h"#define uint unsigned int#define uchar unsigned char#define SCLK_HIGH P3OUT|=BIT3#define SCLK_LOW P3OUT&=~BIT3#define RST_HIGH P3OUT|=BIT1#define RST_LOW P3OUT&=~BIT1#define IO_HIGH P3OUT|=BIT2#define IO_LOW P3OUT&=~BIT2#define IO_OUT P3DIR|=BIT2#define IO_IN P3DIR&=~BIT2#define IO_DA TA P3IN&BIT2uchar num=100;uchar TimeFlag=1; //显示日期时间标志uchar EditFlag=0; //闪烁显示标志uchar KeyValue=0xFF;uchar DNum=0; //D键按的次数//共阳数码管编码表const uchar Code[18]={0xC0,0xF9,0xA4,0xB0,//0,1,2,30x99,0x92,0x82,0xF8,//4,5,6,70x80,0x90,0x88,0x83,//8,9,A,b0xC6,0xA1,0x86,0x8E,//C,d,E,F0xBF,0xFF};//-,全灭//键值编码表const uchar KeyCode[16]={0x77,0x7B,0x7D,0x7E,//0,1,2,30xB7,0xBB,0xBD,0xBE,//4,5,6,70xD7,0xDB,0xDD,0xDE,//8,9,A,b0xE7,0xEB,0xED,0xEE};//C,d,E,Fuchar DS1302[8]={0,0,0,0,0,0,0,0}; //秒,分,时,日,月,星期,年uchar DateBit[8]={0,0,0,0,0,0,16,0}; //日期各位显示的数值uchar TimeBit[8]={0,0,16,0,0,16,0,0}; //时间各位显示的数值uchar BitCode=0x80; //数码管位码初值//时钟初始化函数void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启LFXT1工作在低频模式ACLK不分频最高的标称频率DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率do{IFG1&=~OFIFG;//清除振荡器失效标志for(uint i=255;i>0;i--);}while(IFG1&OFIFG);//判断XT2是否起振BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK 不分频}//端口初始化函数void InitPort(void){P1SEL=0x00;//P1口所有引脚设置为一般的IO口P1DIR=0x0F;//P1.0 P1.1 P1.2 P1.3设置为输出方向P1OUT=0x00;//P1口先输出低电平P1IE=0xF0;//P1.4 P1.5 P1.6 P1.7中断允许P1IES=0xF0;//P1.4 P1.5 P1.6 P1.7下降沿触发中断P3SEL=0x00;//P3口所有引脚设置为一般的IO口P3DIR=0x0E;//P3.1 P3.2 P3.3设置为输出方向P2SEL=0x00;//P2口所有引脚设置为一般的IO口P4SEL=0x00;//P4口所有引脚设置为一般的IO口P2DIR=0xFF;//P2口所有引脚设置为输出方向P4DIR=0xFF;//P4口所有引脚设置为输出方向P2OUT=0x00;//P2口先输出低电平P4OUT=0xFF;//P4口先输出低电平P5SEL&=~BIT7;//P5.7设置为一般的IO口P5DIR|=BIT7;//P5.7设置为输出方向P5OUT&=~BIT7;//P5.7输出低电平来使能74HC573来驱动数码管}//ms级延时子程序void DelayMs(uint ms){while(ms--){for(uint i=0;i<800;i++);}}//数码管扫描显示程序void Display(void){for(uchar i=0;i<8;i++){if(EditFlag==1&&DNum>0){ //判断是否闪烁 if(TimeFlag==0){ //判断日期还是时间闪烁switch(DNum){ //根据D 按的次数判断日期那一位闪烁 case 1:P4OUT=BitCode&0x3F;break; case 2:P4OUT=BitCode&0xCF;break; case 3:P4OUT=BitCode&0xF3;break; case 4:P4OUT=BitCode&0xFE;break; } }else{switch(DNum){ //根据D 按的次数判断时间那一位闪烁 case 1:P4OUT=BitCode&0x3F;break; case 2:P4OUT=BitCode&0xE7;break; case 3:P4OUT=BitCode&0xFC;break; } } }else{P4OUT=BitCode; //输出位码 }if(TimeFlag==1) P2OUT=Code[TimeBit[i]];//判断显示时间还是日期 else P2OUT=Code[DateBit[i]]; BitCode>>=1;//位码右移一位 if(BitCode==0) BitCode=0x80; DelayMs(1); //延时1ms P2OUT=0xFF; } }//10us 级延时子程序 void Delayus(uint us){ while(us--){for(uint i=0;i<800;i++); } }//按键分析程序 void KeyProcess(void){ uchar OutData=0x07;for(uchar i=0;i<4;i++){//扫描4列 OutData|=0xF0; P1OUT=OutData;if(P1IN!=OutData) KeyValue=P1IN; OutData>>=1; }P1OUT=0x00;//恢复原来的值 }//端口1中断处理程序#pragma vector=PORT1_VECTOR __interrupt void Port1INT(void){ for(uint i=1000;i>0;i--); KeyProcess();P1IFG=0x00;//清除中断标志位 }//向DS1302写一字节数据,address 为命令字节 void WriteByte(uchar Command,uchar WriteData){ uchar j,k=1; RST_LOW; SCLK_LOW; RST_HIGH; for(j=0;j<=7;j++){if(Command&k) IO_HIGH; else IO_LOW; SCLK_HIGH; k<<=1; SCLK_LOW; }k=1;for(j=0;j<=7;j++){if(WriteData&k) IO_HIGH; else IO_LOW; SCLK_HIGH; k<<=1; SCLK_LOW; }RST_LOW; }//读取DS1302一字节数据,address 为命令字节 uchar ReadByte(uchar Command){ uchar i,k=1; RST_LOW; SCLK_LOW; RST_HIGH; for(i=0;i<8;i++){if(Command&k) IO_HIGH; else IO_LOW; SCLK_HIGH; k<<=1;if(i!=7) SCLK_LOW; } k=0;for(i=0;i<8;i++){k>>=1; SCLK_LOW; IO_IN;if(IO_DA TA) k|=0x80; IO_OUT; SCLK_HIGH; }RST_LOW; return(k); }//读取DS1302的秒,分,时,日,月,星期,年 void ReadDS1302(){ uchar i;for(i=0;i<=6;i++) DS1302[i]=ReadByte(0x80+2*i+1); //计算时间日期的各位要显示的数据 TimeBit[7]=DS1302[0]&0x0F; TimeBit[6]=DS1302[0]&0x70; TimeBit[6]>>=4;TimeBit[4]=DS1302[1]&0x0F; TimeBit[3]=DS1302[1]&0x70; TimeBit[3]>>=4;TimeBit[1]=DS1302[2]&0x0F; TimeBit[0]=DS1302[2]&0x30; TimeBit[0]>>=4;DateBit[5]=DS1302[3]&0x0F; DateBit[4]=DS1302[3]&0x30; DateBit[4]>>=4;DateBit[3]=DS1302[4]&0x0F; DateBit[2]=DS1302[4]&0x10; DateBit[2]>>=4;DateBit[7]=DS1302[5]&0x07; DateBit[1]=DS1302[6]&0x0F; DateBit[0]=DS1302[6]&0xF0; DateBit[0]>>=4; }//定时器A 初始化 void InitTimerA(void){ TACTL=TASSEL1+ID1+ID0+MC0+TACLR;//选择1/8SMCLK 增计数清除TARCCTL0=CCIE;//CCR0中断允许 比较模式 CCR0=10000;//时间间隔10ms }//定时器A 中断#pragma vector=TIMERA0_VECTOR__interrupt void TimerAINT(void){ num--; if(num==0){EditFlag=!EditFlag; //更新闪烁标志 num=50; } }//时间编辑程序void TimeEdit(uchar flag){ uchar Data,NowData; if(flag){ //判断加1还是减1switch(DNum){ //判断编辑时间的哪一位 case 1:{Data=ReadByte(0x85); //读取小时数据 NowData=Data+1;if((NowData&0x0F)>9) NowData=NowData+6; if(NowData>=0x24) NowData=0;WriteByte(0x84,NowData); //写入小时数据 break; } case 2:{Data=ReadByte(0x83); //读取分数据 NowData=Data+1;if((NowData&0x0F)>9) NowData=NowData+6; if(NowData>=0x60) NowData=0; WriteByte(0x82,NowData); //写入分数据 break; } case 3:{Data=ReadByte(0x81); //读取秒数据 NowData=Data+1;if((NowData&0x0F)>9) NowData=NowData+6; if((NowData&0x7F)>=0x60) NowData=0;WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据 break; } }}else{ switch(DNum){ //判断编辑时间的哪一位 case 1:{Data=ReadByte(0x85); //读取小时数据 if(Data==0){ NowData=0x23; }else{NowData=Data-1;if((NowData&0x0F)>9) NowData=NowData-6;}WriteByte(0x84,NowData); //写入小时数据break;}case 2:{Data=ReadByte(0x83); //读取分数据if(Data==0){NowData=0x59;}else{NowData=Data-1;if((NowData&0x0F)>9) NowData=NowData-6;}WriteByte(0x82,NowData); //写入分数据break;}case 3:{Data=ReadByte(0x81); //读取秒数据if(Data==0){NowData=0x59;}else{NowData=Data-1;if((NowData&0x0F)>9) NowData=NowData-6;}WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据break;}}}}//日期编辑程序void DateEdit(uchar flag){uchar Data,NowData;if(flag){ //判断加1还是减1switch(DNum){ //判断编辑日期的哪一位case 1:{ //年加1Data=ReadByte(0x8d); //读取年数据NowData=Data+1; //年加1if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整if(NowData>=0xA0) NowData=0; //年>=100时,年=0 WriteByte(0x8c,NowData); //年写入DS1302break;} case 2:{Data=ReadByte(0x89); //读取月数据NowData=Data+1; //月加1if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整if(NowData>=0x13) NowData=1; //月>=13,月=1 WriteByte(0x88,NowData); //月写入DS1302break;}case 3:{Data=ReadByte(0x87); //读取日数据NowData=Data+1; //日加1if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整if(NowData>=0x32) NowData=1; //日>=32,日=1 WriteByte(0x86,NowData); //日写入DS1302break;}case 4:{Data=ReadByte(0x8B); //读取星期数据NowData=Data+1; //星期加1if(NowData>=8) NowData=1; //星期>=8,星期=1 WriteByte(0x8A,NowData); //星期写入DS1302break;}}}else{switch(DNum){case 1:{ //年减1Data=ReadByte(0x8d); //读取年数据if(Data==0){NowData=0x99; //如果年=0,减1则为99}else{NowData=Data-1; //年减1if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整}WriteByte(0x8c,NowData); //年写入DS1302break;}case 2:{Data=ReadByte(0x89); //读取月数据NowData=Data-1; //月减1if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整if(NowData==0) NowData=0x12; //月=0,月=12 WriteByte(0x88,NowData); //月写入DS1302break;}case 3:{Data=ReadByte(0x87); //读取日数据NowData=Data-1; //日减1if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整if(NowData==0) NowData=0x31; //日=0,日=31WriteByte(0x86,NowData); //日写入DS1302break;}case 4:{Data=ReadByte(0x8B); //读取星期数据NowData=Data-1; //星期减1if(NowData==0) NowData=7; //星期=0,星期=7WriteByte(0x8A,NowData); //星期写入DS1302break;}}}}//按钮功能函数void KeyFun(void){switch(KeyValue){case 0xE7:{//C键按下切换显示日期还是时间TimeFlag=!TimeFlag;DNum=0;KeyValue=0xFF;break;}case 0xEB:{ //D键按下,DNum加1DNum++;if((TimeFlag==0)&&(DNum>=5)) DNum=0; //如果当前编辑的是日期并且DNum>=5,则编辑完毕,返回正常状态if((TimeFlag==1)&&(DNum>=4)) DNum=0; //如果当前编辑的是时间并且DNum>=4,则编辑完毕,返回正常状态KeyValue=0xFF;break;}case 0xED:{ //E键按下,所选位加1if(TimeFlag==1) TimeEdit(1); //判断编辑日期还是时间else DateEdit(1);KeyValue=0xFF;break;}case 0xEE:{ //F键按下,所选位减1 if(TimeFlag==1) TimeEdit(0); //判断编辑日期还是时间else DateEdit(0);KeyValue=0xFF;break;}}}void main(){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗InitClock();InitPort();InitTimerA();_EINT();//打开中断WriteByte(0x80,ReadByte(0x81)&0x7F); //启动DS1302while(1){KeyFun();ReadDS1302();Display();}}6 ADC12电压测量实验功能:在数码管上显示P6.0输入的电压参考电压为外部#include "msp430x14x.h"#define uint unsigned int#define uchar unsigned char#define ulong unsigned long//共阳数码管编码表uchar Code[18]={0xC0,0xF9,0xA4,0xB0,//0,1,2,30x99,0x92,0x82,0xF8,//4,5,6,70x80,0x90,0x88,0x83,//8,9,A,b0xC6,0xA1,0x86,0x8E,//C,d,E,F0xBF,0xFF};//-,全灭uchar Bit[8]={0,0,0,0,0,0,0,0}; //数码管各位显示的数字uchar BitCode=0x80; //数码管位码初值uint ADCBuf[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//保存采集到的数据ulong Sum=0;//20个数据的和ulong VBuf=0;//电压扩大10000000的值uchar Count=0;//时钟初始化函数void InitClock(void){BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启LFXT1工作在低频模式ACLK不分频最高的标称频率DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率do{IFG1&=~OFIFG;//清除振荡器失效标志for(uint i=255;i>0;i--);}while(IFG1&OFIFG);//判断XT2是否起振BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK不分频}//端口初始化函数void InitPort(void){P2SEL=0x00;//P2口所有引脚设置为一般的IO口P4SEL=0x00;//P4口所有引脚设置为一般的IO口P2DIR=0xFF;//P2口所有引脚设置为输出方向P4DIR=0xFF;//P4口所有引脚设置为输出方向P2OUT=0x00;//P2口先输出低电平P4OUT=0xFF;//P4口先输出低电平P5SEL&=~BIT7;//P5.7设置为一般的IO口P5DIR|=BIT7;//P5.7设置为输出方向P5OUT&=~BIT7;//P5.7输出低电平来使能74HC573来驱动数码管}//ms级延时子程序void DelayMs(uint ms){while(ms--){for(uint i=0;i<800;i++);}}//数码管扫描显示程序void Display(void){for(uchar i=0;i<8;i++){P4OUT=BitCode; //输出位码if(i==0){ //输出段码,如果第三位显示小数点P2OUT=Code[Bit[i]]&0x7F;}else{P2OUT=Code[Bit[i]];}BitCode>>=1;//位码右移一位if(BitCode==0) BitCode=0x80; DelayMs(1); //延时1msP2OUT=0xFF;}}//ADC12初始化void InitADC12(void){P6SEL=0x01;//P6.0为模拟输入ADC12CTL0&=~ENC;//ENC设置为0从而修改ADC12寄存器ADC12MCTL0=INCH_0+SREF_2+EOS;//参考电压为VeREF+和A Vss 输入通道A0ADC12CTL1=CSTARTADD_0+SHP+CONSEQ_2+ADC12SSEL_0+ ADC12DIV_0;//起始地址ADCMEM0,采样脉冲由采样定时器产生,单通道多次转换,内部时钟源不分频ADC12CTL0=MSC+ADC12ON;//采样信号由SHI仅首次触发,打开ADC12模块}//计算电压值void GetV(void){for(uchar i=0;i<20;i++) Sum+=ADCBuf[i];VBuf=Sum/20.0*((2.5*10000000)/4095.0);//计算电压并扩大10000000倍2.5为外部参考电压可用R4调节Sum=0;//计算数码管各位要显示的数值Bit[0]=VBuf/10000000;Bit[1]=VBuf%10000000/1000000;Bit[2]=VBuf%1000000/100000;Bit[3]=VBuf%100000/10000;Bit[4]=VBuf%10000/1000;Bit[5]=VBuf%1000/100;Bit[6]=VBuf%100/10;Bit[7]=VBuf%10;}//定时器A初始化void InitTimerA(void){TACTL=TASSEL1+ID1+ID0+MC0+TACLR;//选择1/8SMCLK 增计数清除TARCCTL0=CCIE;//CCR0中断允许比较模式CCR0=20000;//时间间隔20ms}//定时器A中断#pragma vector=TIMERA0_VECTOR__interruptvoid TimerAINT(void) {ADC12CTL0&=~ENC; ADCBuf[Count]=ADC12MEM0; Count++; if(Count==20) { GetV(); Count=0; }ADC12CTL0|=ENC+ADC12SC;//使能ADC 转换 }void main(){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗 InitClock(); InitPort(); InitTimerA(); InitADC12(); _EINT();//打开中断 while(1){ Display(); } }7 128*64图形液晶显示实验(RT12864) 功能:交替显示一幅图像和文字 #include "msp430x14x.h" #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #define DELAY _NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();#define CD_HIGH P4OUT|=BIT1;DELAY; #define CD_LOW P4OUT&=~BIT1;DELAY; #define E_HIGH P4OUT|=BIT2;DELAY; #define E_LOW P4OUT&=~BIT2;DELAY; #define WR_HIGH P4OUT|=BIT4;DELAY; #define WR_LOW P4OUT&=~BIT4;DELAY; #define RD_HIGH P4OUT|=BIT5;DELAY; #define RD_LOW P4OUT&=~BIT5;DELAY;// ASCII 字模宽度及高度定义 #define ASC_CHR_WIDTH 8 #define ASC_CHR_HEIGHT 16 // ASCII 字模显示为8*16uchar gCurRow,gCurCol;// 当前行列存储行高16 点列宽8点 uchar KEY1=1,KEY2=0; uchar INCOM;uchar uPowArr[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};char turnf[8] = {7,6,5,4,3,2,1,0}; uchar ImageX[64*16]={};//一幅图像数据 //汉字数据*char ASC_MSK[1];typedef struct // 汉字字模数据结构 {char Index[2]; char Msk[32]; }typFNT_GB16; typFNT_GB16 GB_16[]= {};/************************************************/ /* 取当前行数据*/ // 当前行列存储行高16 点列宽8点 /************************************************/ uchar fnGetRow() {return(gCurRow); }/************************************************/ /* 取当前列数据*//************************************************/uchar fnGetCol(){return(gCurCol); }//延时子程序 void DelayMs(uint ms) {while(ms--) {for(uint i=0;i<800;i++); }}//时钟初始化函数 void InitClock(void) {BCSCTL1=RSEL2+RSEL1+RSEL0;//XT2开启 LFXT1工作在低频模式ACLK 不分频 最高的标称频率DCOCTL=DCO2+DCO1+DCO0;//DCO 为最高频率 do{IFG1&=~OFIFG;//清除振荡器失效标志 for(uint i=255;i>0;i--);}while(IFG1&OFIFG);//判断XT2是否起振 BCSCTL2=SELM1+SELS;//MCLK SMCLK 时钟源为TX2CLK 不分频}//端口初始化函数 void InitPort() {P1SEL=0x00;//P1口所有引脚设置为一般的IO 口P1DIR=0xFC;//P1.2 P1.3 P1.4 P1.5 P1.6 P1.7设置为输出方向 P1OUT=0xff;//P1口先输出高电平 P1IE=0x03;//P1.0 P1.1中断允许 P1IES=0x03;//P1.0 P1.1下降沿触发中断P2SEL=0x00;//P2口所有引脚设置为一般的IO 口 P4SEL=0x00;//P4口所有引脚设置为一般的IO 口 P2DIR=0xFF;//P2口所有引脚设置为输出方向 P4DIR=0xFF;//P4口所有引脚设置为输出方向 P2OUT=0x00;//P2口先输出低电平 P4OUT=0xFF;//P4口先输出高电平 }void KeyProcess() {if(P1IN|BIT0==0) KEY1=1; if(P1IN|BIT1==0) KEY2=1; }//端口1中断处理程序#pragma vector=PORT1_VECTOR __interrupt void Port1INT(void){ DelayMs(5); KeyProcess();P1IFG=0x00;//清除中断标志位 }//读状态字 void Lcdsta() {E_HIGH; P2DIR=0x00; CD_HIGH; RD_LOW; WR_HIGH; INCOM=P2IN; E_LOW; P2DIR=0xff; }/************************************************/ /* 状态位STA1,STA0判断读写指令和读写数据*/ /* 在读写数据或者写入命令前必须保证均为1 */ /************************************************/ void STA01() {uchar i; for(i=10;i>0;i--) {if((INCOM&0x03)==0x03) // 读取状态 {break; } } }/********************************************/ /* 检查STA2,如果STA2=1 为自动读状态*/ /*****************************************/ void STA2() {unsigned char i; for(i=10;i>0;i--) {if((INCOM&0x04)==0x04) {break; } } }/***********************************************//* 状态位STA3 判断STA3 = 1 数据自动写状态*//***********************************************/ void STA3(){unsigned char i;for(i=10;i>0;i--){if((INCOM&0x08)==0x08){break;}}}/************************************************/ /* 状态位STA6 判断STA6 =1 屏读/屏拷贝状态*//************************************************/ void STA6(){unsigned char i;for(i=10;i>0;i--){if((INCOM&0x40)==0x40){break;}}}/************************//* 写指令*//************************/void WriteCommand(uchar Command){STA01();E_HIGH;CD_HIGH;WR_LOW;P2OUT=Command;DELAY;E_LOW;}/************************//* 写数据*//************************/ void fnPR13(uchar Data){STA01();E_HIGH;CD_LOW;WR_LOW;P2OUT=Data;DELAY;DELAY;E_LOW;}/************************//* 写双参数的指令*//************************/void fnPR1(char Cmd1,char Cmd2,char Dat) {fnPR13(Cmd1);fnPR13(Cmd2);WriteCommand(Dat);}/************************//* 写单参数的指令*//************************/void fnPR11(char Cmd,char Dat){fnPR13(Cmd);WriteCommand(Dat);}/************************//* 写无参数的指令*//************************/void fnPR12(char Dat){WriteCommand(Dat);}/************************//* 设置当前地址RAM里*//************************/void fnSetPos(char urow,char ucol){。

MSP430按键输入和led点阵显示

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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按键篇
经过一短时间的学习,下面,亲自动手编写一下程序吧。
程序的目的是:按下按键,控制LED的亮和灭。短按键,则小灯亮1秒,然后灭; 长按键,小灯常亮。
首先,完成键盘的扫描程序。
第一点:如果是扫描,就要用到定时器。我想设计定时器每隔IOms扫描一次按
键。
定时器,我选用定时器A。它的定时中断函数如下:
函数名称:TimerA_ISR
Else
TIME_1_S=0;
If(FlagLcd==2)
TIME_L_S=1;
}
If((TIME_1_S>0)||( TIME_L_S==1))
功能:定时器A的中断服务函数
参 数:无
返回值 :无********************************************/#pragma vector=TIMERAO_VECTOR__interrupt void TimerA_ISR(void){
GetKey();
}
上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用GetKey()函数一次。GetKey()函数就是扫描键盘按键的函数了。在GetKey()函数中,会 根据按键类型(长按/短按)返回不同的数值。根据返回的数值,做小灯亮法的 操作。那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量ucharFlagLcd;来保存返回值。这个变量在全局变量中定义,以保证它的作用 域。
}
下面是键盘扫描函数:
Un Sig ned Char GetKeyO
{
Un Sig ned Char keyRetu=0; //返回的按键值
StatiC UnSigned Char s_keyState=0,keyTime=0; //按键状态,按键按下的时间
计数器
switch (s_keyState)
s_keyState=3; //转到状态3 keyTime=0; //清零按键时间计数器keyRetu=2; //输出2
}
}
break;
case 3: if((P1IN&0x01)==1) //检测到按键松开{
s_keyState=O; //状态转到状态O
}_
else
{
s_keyState=3; //转到状态3
{
s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
}
break;
case 2: if((P1IN&0x01)==1) //检测到按键松开{
s_keyState=0; //状态转到状态0 keyRetu=1; //输出1
}
else
{if(++keyTime>=50) //按下时间>1s{
{
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
那么定时函数就变为
#pragma vector=TIMERAO_VECTOR
__interrupt void TimerA_ISR(void)
{
FlagLcd =GetKey();
}
定时器中断的时间间隔,我在主函数中定义。
这样写:
CCTLO = CCIE; //使能CCR冲断
CCRO=4O;//设定周期O.O1S
TACTL = TASSEL_1 +ID_3 +MC_1;//定时器A的时钟源选择ACLK增计数模 式这样,定时器这块就算完工了。那么,下面进行按键扫描程序。
按键的定义是这样的,根据我板子的按键原理图如下
Pl +
PlA
Pl了
这是一个矩阵键盘。其中KEY就是外部高电平3.3V。我只想用其中的P1.0作为 这次试验的按键。那么,做些设置就可以了。将P1.7方向设置为输出,并输出
#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++;
在主程序中定义全局变量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))
电平为低。这样,才能实现当K1按下时,P1.0输入为低;当K1抬起时,P1.0输Pad(VOid)
{_
P1DIR = 0xfe; /∕P1.0设置为输入状态,P1.1~P1.7设置为输出状态
P10UT &= 0x7f; // P1.0~P1.6输出高电平,P1.7输出低电平
}_
break;
}
return keyRetu;
}
上面这个扫描函数,根据按键K1是长按还是短按,返回不同的值:长按,返回
2;短按,返回1。
获得了返回值以后,就要对LED进行操作了。
我的板子的LED如下图
LED是LED供电高电平,这里我只想用其中的
P2DIR = 0xff; //设置P2口方向为输出
P2OUT = 0xff; //设置P2口输出高电平那么P2OUT = 0xfe,贝U LED亮;P2OUT = 0xff,贝U LED灭。这个很好实现。但 是,怎么样才能持续亮1s呢?这个问题还需要定时器来解决。我在这里还利用 定时器A来完成这个任务。
TIME_1_S++;
Else
TIME_1_S=0;
}
这样,在控制LED的时候,可以这样写
If(TIME_1_S>0)
P2OUT=0xfe;
Else
P2OUT=0xff;
就实现了亮1S的效果。
那么长按键的时候呢,则需要再做一下处理。
在主程序中定义全局变量unsigned int TIME_L_S=0;然后再定时器中断函数中做些改动
相关文档
最新文档