基于MSP430F249的电子时钟(完整代码+protues仿真图+系统流程图)
设计要求
以MSP430单片机为核心的时钟,在LCD显示器上显示当前的时间:
使用字符型LCD显示器显示当前时间。显示格式为“时时:分分:秒秒”。
用4个功能键操作来设置当前时间。功能键K1~K4功能如下。
K1—进入设置现在的时间。
K2—设置小时。
K3—设置分钟。
K4—确认完成设置。
程序执行后工作指示灯LED闪动,表示程序开始执行。
整体功能实现方案
利用 MSP430F249 单片机内置的时钟作为时钟源,选择 TimerA 定时器进行 1 秒定时,
选择增计数模式,定时时间到进入 TimerA 中断服务程序, LED 输出取反,时间值按秒自
增, 完成时钟的正常运行。选择 Port2.0 口作为外部中断源,选择高跳低作为触发沿,
外部中断触发后进入设置模式,利用四个按键的不同功能完成年,月,日, 时,分数值的设置。
按键功能分析
要完成年、月、日、时、分数值的设置按键则需要实现以下功能:
数值+键:按下时数值增加;
数值-键:按下时数值减小;
进入/退出日期设置总键: 按下进入/退出设置日期模式( 年/月/日);
进入/退出年份设置键: 按下进入/退出设置年份模式;
进入/退出月份设置键: 按下进入/退出设置月份模式;
进入/日期设置键: 按下进入/退出设置日期模式( 日);
进入/小时设置键:按下进入/退出设置小时模式;
进入/分钟设置键:按下进入/退出设置分钟模式;
进入设置键: 按下时进入设置模式;
退出设置键:按下时退出设置模式;
系统流程
整体系统运行结构如下图:
主程序(main())流程图
主程序运行结构图如下:
TIMER_A中断流程图
外部中断程序流程图
根据设计要求,外部按键需实现的结构如下图
硬件部分
主控芯片
MSP430f249引脚图
显示器件
LCD1602
表1:LCD1602引脚功能表
编号 | 符号 | 引脚说明 | 标号 | 符号 | 引脚说明 |
---|---|---|---|---|---|
1 | VSS | 电源地 | 9 | D2 | 数据 |
2 | VDD | 电源正极 | 10 | D3 | 数据 |
3 | VL | 液晶显示偏压 | 11 | D4 | 数据 |
4 | RS | 数据/命令选择 | 12 | D5 | 数据 |
5 | R/W | 读/写选择 | 13 | D6 | 数据 |
6 | E | 使能信号 | 14 | D7 | 数据 |
按键设计
单片机MSP430F249按键功能表:
名称 | 功能 |
---|---|
K1 | 进入设置键 \ 进入/退出日期设置总键 \ 数值+键(年,月,时,分); |
K2 | 进入/退出年份设置键 \ 进入/小时设置键 \ 数值+键(日); |
K3 | 进入/退出月份设置键 \ 进入/分钟设置键 \ 数值-键(日); |
K4 | 退出设置键 \ 进入/退出日期设置键 \ 数值-键(年,月,时,分); |
单片机引脚与按键连接表:
单片机引脚 | 引脚功能 | 单片机引脚 | 引脚功能 |
---|---|---|---|
P2.0 | K1 | P1.0 | LEDred |
P2.1 | K2 | P1.1 | LEDgreen |
P2.2 | K3 | ||
P2.3 | K4 |
LCD1602显示屏引脚与MSP430F249单片机连接表:
LCD1602引脚 | MSP430F249单片引脚 |
---|---|
RS | P3.7 |
RW | P3.6 |
E | P3.5 |
D0-D7 | P4.0-P4.7 |
仿真结果
主控芯片连接图
指示灯状态描述
Set model \ Setday model |Sethour model \ Setyear model
Setminute model \ Setmonth model | Setdate model
按键连接图
a,b,c,d分别连接R1-R4右上方的端子
显示屏连接图
源代码
main函数:
/* |--------------------------MSP430F249-----------------------------| *
* | P1.0 P1.1 P2.0 P2.1 P2.2 P2.3 P4.0~P4.7 P3.5 P3.6 P3.7 | *
* | | | | | | | | | | | | *
* | LED LED K1 K2 K3 K4 LCD_D0~D7 EN RW RS | *
* | red green | *
* |-----------------------------------------------------------------| *
*If you want to set the time, follow the statement below: *
*Press the key1 until both the red LED and green LED light to enter the setting*
*model. *
*Continue press the key1 until both light off to enter the setting date model *
*press the key2 to set/quit set year model, key3 pre to enter/quit set month *
*press key1 to increase number and key4 to decrease. *
*Press key4 to enter/quit set day model,press key1 to increase number and key4 *
*to decrease. *
*Press the key2 until the red LED light and green LED off to enter the setting *
*hour moudle. *
*In this model, press key1 let the number of hours increas and press the key4 *
*let the number decraese. *
*when you finish setting,press the key2 to quit hour setting model. *
*Press the key3 until the red LED off and green LED light to enter the setting *
*minute moudle. *
*Setting minutes number same as hours except change the key2 to key3. *
*When you finish setting, press the key4 to quit setting model. *
* *
* Author: Ycc Mhw *
* date: 2 0 2 0 - 0 6 - 0 4 *
********************************************************************************/
#include"MSP430.h"
#include"config.h"
#include"LCD1602.h"
#include<stdio.h>
#include"clock.h"
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
CCR0=65535; //count value
P1DIR |= 0x03; // P1.0 output
CCTL0 = CCIE; // CCR0 interrupt enabled
TACTL = TASSEL_2 + MC_2; // ACLK, contmode
P1OUT|=BIT0; //let the P1.0 output 1
/*set the external interrput pin*/
P2IE |= 0x01; // P2.0 interrupt enabled
P2IES |= 0x01; // P2.0 Hi/lo edge
P2IFG &= ~0x01; // P2.0 IFG cleared
/*initial the lcd1602 and the port connect with lcd1602*/
Port1602_init();
LCD1602_init();
LCD1602_clear();
display();
for(;;)
{
__bis_SR_register(LPM0_bits + GIE); //enter the LPM0 open the general interrupt
}
}
/*TimerA interrupt serve programme change the number of clock varible*/
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMERA0_VECTOR))) Timer_A (void)
#else
#error Compiler not supported!
#endif
{
P1OUT ^= 0x01; // Toggle P1.0
CCR0 += 50000; // Add Offset to CCR0
S=S+1;
if(S>59)
M=M+1,S=0;
if(M>59)
H=H+1,M=0;
if(H>23)
D=D+1,H=0;
if(D>30)
MON=MON+1,D=0;
if(MON>12)
Y=Y+1,MON=0;
display();
}
/*interrupt serve programme change the number of clock varible*/
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_2 (void)
#else
#error Compiler not supported!
#endif
{
P1OUT = 0x03; // P1.0 = toggle
K1=BIT0;
K2=BIT1;
K3=BIT2;
K4=BIT3;
char keyvalue;
keyvalue=getkey();
do
{
keyvalue=getkey();
if(keyvalue==K1)
setdate();
if(keyvalue==K2)
sethour();
if(keyvalue==K3)
setmin();
}while(keyvalue!=K4);
P2IFG &= ~0x01; // P1.3 IFG cleared
P1OUT=BIT0;
}
功能函数"clock.h"
IntH=0,M=0,S=0,D=3,MON=6,Y=2020; //variable of clock: Y=year, MON=month, D=day, H:hour, M=minute, S=second
unsigned char K1, K2, K3, K4; //setting button
unsigned char table[]={0,1,2,3,4,5,6,7,8,9}; //time number list
char getkey(void);
void setyear(void);
void setmonth(void);
void setday(void);
void sethour(void);
void setmin(void);
void display(void);
void display_year(void);
char getkey(void)
{
char x,y;
x=(P2IN&0x0F);
x=(x^0x0F);
y=x;
delay_ms(100); // key-virbation eliminate
x=(P2IN&0x0F);
x=(x^0x0F);
if(x==y)
return x;
else
return 0;
}
void setdate(void)
{
P1OUT=0x00;
K1=BIT0;
K2=BIT1;
K3=BIT2;
K4=BIT3;
char keyvalue;
keyvalue=getkey();
do
{
keyvalue=getkey();
if(keyvalue==K2)
setyear();
if(keyvalue==K3)
setmonth();
if(keyvalue==K4)
setday();
}
while(keyvalue!=K1);
P1OUT=0x03;
}
/*set the number of years*/
void setyear(void)
{
unsigned char keyvalue;
P1OUT=BIT0;
keyvalue=getkey();
do
{
keyvalue=getkey();
if(keyvalue==BIT0)
{
Y=Y+1;
}
/*refresh the new setting number of year*/
display_year();
if(keyvalue==BIT3)
{
Y=Y-1;
}
/*refresh the new setting number of year*/
display_year();
}
while(keyvalue!=BIT1);
P1OUT=0x00;
}
/*set the number of monthes*/
void setmonth(void)
{
unsigned char keyvalue;
P1OUT=BIT1;
keyvalue=getkey(); //ensure the value of month in 1~12
do
{
keyvalue=getkey();
if(keyvalue==BIT0)
{
if(MON<12)
MON=MON+1;
if(MON==12)
M=1;
}
/*refresh the new setting number of month*/
LCD1602_write_char(8,0,table[MON/10]+0x30);
LCD1602_write_char(9,0,table[MON%10]+0x30);
if(keyvalue==BIT3)
{
if(MON>0)
MON=MON-1;
if(MON==0)
MON=12;
}
/*refresh the new setting number of month*/
LCD1602_write_char(8,0,table[MON/10]+0x30);
LCD1602_write_char(9,0,table[MON%10]+0x30);
}
while(keyvalue!=BIT2);
P1OUT=0x00;
}
/*set the number of day*/
void setday(void)
{
unsigned char keyvalue;
P1OUT=0x03;
keyvalue=getkey(); // ensure the value of day in 1~30
do
{
keyvalue=getkey();
if(keyvalue==BIT1)
{
if(D<30)
D=D+1;
if(D==30)
D=1;
}
/*refresh the new setting number of day*/
LCD1602_write_char(11,0,table[D/10]+0x30);
LCD1602_write_char(12,0,table[D%10]+0x30);
if(keyvalue==BIT2)
{
if(D>1)
D=D-1;
if(D==1)
D=30;
}
/*refresh the new setting number of day*/
LCD1602_write_char(11,0,table[D/10]+0x30);
LCD1602_write_char(12,0,table[D%10]+0x30);
}
while(keyvalue!=BIT3);
P1OUT=0x00;
}
/*set the number of hours*/
void sethour(void)
{
unsigned char keyvalue;
P1OUT=BIT0;
keyvalue=getkey(); // ensure the value of hour in 0~23
do
{
keyvalue=getkey();
if(keyvalue==BIT0)
{
if(H<23)
H=H+1;
if(H==23)
H=0;
}
/*refresh the new setting number of hour*/
LCD1602_write_char(4,1,table[H/10]+0x30);
LCD1602_write_char(5,1,table[H%10]+0x30);
if(keyvalue==BIT3)
{
if(H>0)
H=H-1;
if(H==0)
H=23;
}
/*refresh the new setting number of hour*/
LCD1602_write_char(4,1,table[H/10]+0x30);
LCD1602_write_char(5,1,table[H%10]+0x30);
}
while(keyvalue!=BIT1);
P1OUT|=BIT1;
}
/*set the number of minutes*/
void setmin(void)
{
unsigned char keyvalue;
P1OUT=BIT1;
keyvalue=getkey();
while(keyvalue!=BIT2)
{
keyvalue=getkey();
if(keyvalue==BIT0) // ensure the value of minute in 0~59
{
if(M<59)
M=M+1;
if(M==59)
M=0;
}
/*refresh the new setting number of minute*/
LCD1602_write_char(7,1,table[M/10]+0x30);
LCD1602_write_char(8,1,table[M%10]+0x30);
if(keyvalue==BIT3)
{
if(M>0)
M=M-1;
if(M==0)
M=59;
}
/*refresh the new setting number of minute*/
LCD1602_write_char(7,1,table[M/10]+0x30);
LCD1602_write_char(8,1,table[M%10]+0x30);
}
while(keyvalue!=BIT2);
P1OUT|=BIT0;
}
/*display the time with date in a |yyyy-mm-dd|
format like | hh:mm:ss |*/
void display(void)
{
LCD1602_write_char(7,0,'-');
LCD1602_write_char(10,0,'-');
/*display the year
display_year();
/*display the month*/
LCD1602_write_char(8,0,table[MON/10]+0x30);
LCD1602_write_char(9,0,table[MON%10]+0x30);
/*display the day*/
LCD1602_write_char(11,0,table[D/10]+0x30);
LCD1602_write_char(12,0,table[D%10]+0x30);
LCD1602_write_char(6,1,':');
LCD1602_write_char(9,1,':');
/*display the hour*/
LCD1602_write_char(4,1,table[H/10]+0x30);
LCD1602_write_char(5,1,table[H%10]+0x30);
/*display the minute*/
LCD1602_write_char(7,1,table[M/10]+0x30);
LCD1602_write_char(8,1,table[M%10]+0x30);
/*display the second*/
LCD1602_write_char(10,1,table[S/10]+0x30);
LCD1602_write_char(11,1,table[S%10]+0x30);
}
void display_year(void)
{
int t,h,d,s;
t=Y/1000;
h=(Y-t*1000)/100;
d=(Y-t*1000-h*100)/10;
s=(Y-t*1000-h*100)%10;
LCD1602_write_char(3,0,table[t]+0x30);
LCD1602_write_char(4,0,table[h]+0x30);
LCD1602_write_char(5,0,table[d]+0x30);
LCD1602_write_char(6,0,table[s]+0x30);
}
LCD1602驱动程序"LCD1602.h"
#define RS_CLR P3OUT &= ~BIT7 //RS置低
#define RS_SET P3OUT |= BIT7 //RS置高
#define RW_CLR P3OUT &= ~BIT6 //RW置低
#define RW_SET P3OUT |= BIT6 //RW置高
#define EN_CLR P3OUT &= ~BIT5 //E置低
#define EN_SET P3OUT |= BIT5 //E置高
#define DataPort P4OUT //设置数据口
#include "Config.h"
//*************************************************************************
// 初始化IO口子程序
//*************************************************************************
void Port1602_init()
{
P4SEL = 0x00;
P4DIR = 0xFF;
P3SEL = 0x00;
P3DIR|= BIT5 + BIT6 + BIT7; //控制口设置为输出模式
}
//***********************************************************************
// 显示屏命令写入函数
//***********************************************************************
void LCD1602_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com; //命令写入端口
delay_ms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏数据写入函数
//***********************************************************************
void LCD1602_write_data(unsigned char data)
{
RS_SET;
RW_CLR;
EN_SET;
DataPort = data; //数据写入端口
delay_ms(5);
EN_CLR;
}
//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD1602_clear(void)
{
LCD1602_write_com(0x01); //清屏幕显示
delay_ms(5);
}
//***********************************************************************
// 显示屏字符串写入函数
//***********************************************************************
void LCD1602_write_str(unsigned int x,unsigned int y,char *s)
{
if (y == 0)
{
LCD1602_write_com(0x80 + x); //第一行显示
}
else
{
LCD1602_write_com(0xC0 + x); //第二行显示
}
while (*s)
{
LCD1602_write_data( *s);
s ++;
}
}
//***********************************************************************
// 显示屏单字符写入函数
//***********************************************************************
void LCD1602_write_char(unsigned char x,unsigned char y,unsigned char data)
{
if (y == 0)
{
LCD1602_write_com(0x80 + x); //第一行显示
}
else
{
LCD1602_write_com(0xC0 + x); //第二行显示
}
LCD1602_write_data( data);
}
//***********************************************************************
// 显示屏初始化函数
//***********************************************************************
void LCD1602_init(void)
{
LCD1602_write_com(0x38); //显示模式设置
delay_ms(5);
LCD1602_write_com(0x08); //显示关闭
delay_ms(5);
LCD1602_write_com(0x01); //显示清屏
delay_ms(5);
LCD1602_write_com(0x06); //显示光标移动设置
delay_ms(5);
LCD1602_write_com(0x0C); //显示开及光标设置
delay_ms(5);
}
//***********************************************************************
// LCD1602显示函数,只显示一次
//***********************************************************************
void Test_LCD1602(void)
{
uchar i,j,*p;
Port1602_init(); //系统初始化,设置IO口属性
delay_ms(20); //延时20ms
LCD1602_init(); //液晶参数初始化设置
LCD1602_clear(); //清屏
for(j=0;j<1;j++)
{
i = 1;
p = "display test"; //字符串输出显示
LCD1602_clear();
LCD1602_write_str(0,0,"Welcome");
delay_ms(250);
while (*p) {
LCD1602_write_char(i,1,*p); //单个字符输出显示
i ++;
p ++;
delay_ms(250); //延时250ms
}
delay_ms(250);
}
}
驱动程序部分来源于网络
2022.05.04更新·······
首先感谢大家的评论,看到许多朋友都在问配置头文件,这个文件的作用时对lcd显示屏的接口进行相关配置,相关代码也是从网上找的,下面附上源代码
config.h
/********************************************************************
//DM430-L型最小系统板外部资源配置文件Config.h
//包含板载各个资源的硬件配置,如果用户使用过程中,对应的硬件发生了更改,可利用该头文件更改使用
//SD/MMC卡初始化硬件配置未包含
//调试环境:EW430 V5.30
//作者:www.avrgcc.com
//时间:2014.03.01
********************************************************************/
#ifndef __CONFIG_H
#define __CONFIG_H
//延时函数,IAR自带,经常使用到
#define CPU_F ((double)8000000) //外部高频晶振8MHZ
//#define CPU_F ((double)32768) //外部低频晶振32.768KHZ
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
//自定义数据结构,方便使用
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//#if 0注释,1使用
#if 0
//8个LED灯,连接在P6口,可通过断开电源停止使用,ADC使用时断开电源
#define LED8DIR P6DIR
#define LED8 P6OUT //P6口接LED灯,8个
//4个独立按键连接在P10~P13
#define KeyPort P1IN //独立键盘接在P10~P13
//串口波特率计算,当BRCLK=CPU_F时用下面的公式可以计算,否则要根据设置加入分频系数
#define baud 9600 //设置波特率的大小
#define baud_setting (uint)((ulong)CPU_F/((ulong)baud)) //波特率计算公式
#define baud_h (uchar)(baud_setting>>8) //提取高位
#define baud_l (uchar)(baud_setting) //低位
//RS485控制管脚,CTR用于控制RS485处于收或者发状态
#define RS485_CTR1 P5OUT |= BIT2; //控制线置高,RS485发送状态
#define RS485_CTR0 P5OUT &= ~BIT2; //控制线置低,RS485接收状态
//2.8寸TFT彩屏显示控制相关硬件配置
#define RS_CLR P5OUT &= ~BIT5 //RS置低
#define RS_SET P5OUT |= BIT5 //RS置高
#define RW_CLR P5OUT &= ~BIT6 //RW置低
#define RW_SET P5OUT |= BIT6 //RW置高
#define RD_CLR P5OUT &= ~BIT7 //E置低
#define RD_SET P5OUT |= BIT7 //E置高
#define CS_CLR P5OUT &= ~BIT0 //CS置低
#define CS_SET P5OUT |= BIT0 //CS置高
#define RST_CLR P5OUT &= ~BIT3 //RST置低
#define RST_SET P5OUT |= BIT3 //RST置高
#define LE_CLR P5OUT &= ~BIT1 //LE置低
#define LE_SET P5OUT |= BIT1 //LE置高
//2.8寸TFT彩屏触摸屏控制相关硬件配置
#define PEN_CLR P2OUT &= ~BIT0 //PEN置低,触碰触摸屏时,Penirq引脚由未触摸时的高电平变为低电平
#define PEN_SET P2OUT |= BIT0 //PEN置高
#define PEN (P2IN & 0x01) //P2.0输入的值
#define TPDO_CLR P2OUT &= ~BIT1 //TPDO置低
#define TPDO_SET P2OUT |= BIT1 //TPDO置高
#define TPDOUT ((P2IN>>1)&0x01) //P2.1输入的值
#define BUSY_CLR P2OUT &= ~BIT3 //BUSY置低
#define BUSY_SET P2OUT |= BIT3 //BUSY置高
#define TPDI_CLR P2OUT &= ~BIT4 //TPDI置低
#define TPDI_SET P2OUT |= BIT4 //TPDI置高
#define TPCS_CLR P2OUT &= ~BIT5 //TPCS置低
#define TPCS_SET P2OUT |= BIT5 //TPCS置高
#define TPCLK_CLR P2OUT &= ~BIT6 //TPCLK置低
#define TPCLK_SET P2OUT |= BIT6 //TPCLK置高
//彩屏/12864液晶/1602液晶的数据口,三液晶共用
#define DataDIR P4DIR //数据口方向
#define DataPort P4OUT //P4口为数据口
//12864/1602液晶控制管脚
#define RS_CLR P5OUT &= ~BIT5 //RS置低
#define RS_SET P5OUT |= BIT5 //RS置高
#define RW_CLR P5OUT &= ~BIT6 //RW置低
#define RW_SET P5OUT |= BIT6 //RW置高
#define EN_CLR P5OUT &= ~BIT7 //E置低
#define EN_SET P5OUT |= BIT7 //E置高
#define PSB_CLR P5OUT &= ~BIT0 //PSB置低,串口方式
#define PSB_SET P5OUT |= BIT0 //PSB置高,并口方式
#define RST_CLR P5OUT &= ~BIT1 //RST置低
#define RST_SET P5OUT |= BIT1 //RST置高
//12864应用指令集
#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H
#define AC_INIT 0x02 //将AC设置为00H。且游标移到原点位置
#define CURSE_ADD 0x06 //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
#define FUN_MODE 0x30 //工作模式:8位基本指令集
#define DISPLAY_ON 0x0c //显示开,显示游标,且游标位置反白
#define DISPLAY_OFF 0x08 //显示关
#define CURSE_DIR 0x14 //游标向右移动:AC=AC+1
#define SET_CG_AC 0x40 //设置AC,范围为:00H~3FH
#define SET_DD_AC 0x80 //设置DDRAM AC
#define FUN_MODEK 0x36 //工作模式:8位扩展指令集
//颜色代码,TFT显示用
#define White 0xFFFF //显示颜色代码
#define Black 0x0000
#define Blue 0x001F
#define Blue2 0x051F
#define Red 0xF800
#define Magenta 0xF81F
#define Green 0x07E0
#define Cyan 0x7FFF
#define Yellow 0xFFE0
//NRF2401模块控制线
#define RF24L01_CE_0 P1OUT &=~BIT5 //CE在P15
#define RF24L01_CE_1 P1OUT |= BIT5
#define RF24L01_CSN_0 P2OUT &=~BIT7 //CS在P27
#define RF24L01_CSN_1 P2OUT |= BIT7
#define RF24L01_SCK_0 P3OUT &=~BIT3 //SCK在P33
#define RF24L01_SCK_1 P3OUT |= BIT3
#define RF24L01_MISO_0 P3OUT &=~BIT2 //MISO在P32
#define RF24L01_MISO_1 P3OUT |= BIT2
#define RF24L01_MOSI_0 P3OUT &=~BIT1 //MOSI在P31
#define RF24L01_MOSI_1 P3OUT |= BIT1
#define RF24L01_IRQ_0 P1OUT &=~BIT4 //IRQ在P14
#define RF24L01_IRQ_1 P1OUT |= BIT4
//DS18B20控制脚,单脚控制
#define DQ_IN P1DIR &= ~BIT7 //设置输入,DS18B20接单片机P53口
#define DQ_OUT P1DIR |= BIT7 //设置输出
#define DQ_CLR P1OUT &= ~BIT7 //置低电平
#define DQ_SET P1OUT |= BIT7 //置高电平
#define DQ_R P1IN & BIT7 //读电平
//红外接收头H1838控制脚,单脚控制
#define RED_IN P1DIR &= ~BIT6 //设置输入,红外接收头接单片机PE3口
#define RED_OUT P1DIR |= BIT6 //设置输出
#define RED_L P1OUT &= ~BIT6 //置低电平
#define RED_H P1OUT |= BIT6 //置高电平
#define RED_R (P1IN & BIT6) //读电平
#endif
//***********************************************************************
// 系统时钟初始化,外部8M晶振
//***********************************************************************
void Clock_Init()
{
uchar i;
BCSCTL1&=~XT2OFF; //打开XT2振荡器
BCSCTL2|=SELM1+SELS; //MCLK为8MHZ,SMCLK为8MHZ
do{
IFG1&=~OFIFG; //清楚振荡器错误标志
for(i=0;i<100;i++)
__no_operation();
}
while((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待
IFG1&=~OFIFG;
}
//***********************************************************************
// 系统时钟初始化,内部RC晶振
//***********************************************************************
void Clock_Init_Inc()
{
// DCOCTL = DCO0 + DCO1 + DCO2; // Max DCO
// BCSCTL1 = RSEL0 + RSEL1 + RSEL2; // XT2on, max RSEL
DCOCTL = 0x60 + 0x00; //DCO约3MHZ,3030KHZ
BCSCTL1 = DIVA_0 + 0x07;
BCSCTL2 = SELM_2 + DIVM_0 + SELS + DIVS_0;
}
//***********************************************************************
// 系统时钟初始化,外部32.768K晶振
//***********************************************************************
void Clock_Init_Ex32768()
{
uchar i;
BCSCTL2|=SELM1 + SELM0 + SELS; //MCLK为32.768KHZ,SMCLK为8MHZ
do{
IFG1&=~OFIFG; //清楚振荡器错误标志
for(i=0;i<100;i++)
__no_operation();
}
while((IFG1&OFIFG)!=0); //如果标志位1,则继续循环等待
IFG1&=~OFIFG;
}
//***********************************************************************
// MSP430内部看门狗初始化
//***********************************************************************
void WDT_Init()
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
}
#endif