接通电源之后,系统进行初始化,按下设置键S1或者S2,LCD进入时间设置界面,先使用齿轮确定要设定的位置(时、分、秒),按下s1按键进行确认,开始设置这个位置,可以使用齿轮电位计进行对该位置的数进行加减,设置数值,设置完成之后按下S1键进行确认,然后重新使用齿轮电位计确定要设置的位置,重复上述操作。全部设置完成之后,按下S2确认完成设置时间。接着进入倒计时器界面。计时完成之后,LED闪烁,提醒。
<!--EndFragment-->
技术难点
4.2.1 汉字LCD显示
运用汉字字库生成软件,将汉字依据大小尺寸变化,进行字模转换,转换成可以在LCD显示的16进制的数组。并在需要的是使用Dogs102x6_imageDraw()函数,将汉字在LCD上显示出来。
4.2.2 时间的设置
在时间的设置上,想过两个方案。
第一个方案是,运用触摸键 TI_CAPT_Slider(&slider)这行代码来进行对时间的设置,完成对时间的时、分、秒的移动以及各位数值的加减。但是由于资料不足,对触摸键的机理了解的不足,程序出现的严重的BUG,比如按下一次触摸键,数值会一直在不断地在进行加减。
第二个方案是,运用齿轮电位计Wheel_getPosition()函数以及Wheel_getValue()函数,通过获取齿轮电位计的采样值,来进行对时间的赋值。显然这一方案,并没有出现很大的问题。当然,由于Wheel_getValue()的返回值过大,我对其处于一定的数值,将之返回的采样值限定在一定的范围以内。
4.2.3 倒计时函数
对于倒计时,为了简化程序,提高代码的重用性,我将倒计时的过程,简化成为一个函数countDowm()函数。在其中,遇到一个很大的问题就是,由于缺少C语言的程序的编写经验,忽视了uint8_t数据类型是一种无符号整型,没有所谓的负数概念,故导致显示出现乱码。所以,将该数据类型改为int整型。
4.2.4 设置时间时数值的显示
为了区别设置的数值与不被设置的数值,特写了一个函数shining(),运用反色,将之与其他数值进行区别。
4.2.5 按键被按下与否
按键S1、S2的按下与否,是由buttonPress这一变量决定的,当buttonPress为0时,表示未被按下;当buttonPress为1时,表示已被按下。而按键每一次被按下,系统会自动给buttonPress赋值1.所以,每次按下按键之后,我们都应该给buttonPress赋值0,为下一次的按键按下与否判断,做好准备。
附录 源程序
1.主函数
#include <stdint.h>
#include "msp430.h"
#include "HAL_PMM.h"
#include "HAL_UCS.h"
#include "HAL_Board.h"
#include "HAL_Buttons.h"
#include "HAL_Cma3000.h"
#include "HAL_Dogs102x6.h"
#include "HAL_Menu.h"
#include "HAL_Wheel.h"
#include "LaunchpadDef.h"
#include "LPM.h"
#include "MassStorage.h"
#include "Mouse.h"
#include "PMM.h"
#include "lab.h"
uint16_t timeoutCounter;
// This image has been created by ImageDog using 'ti_bug.jpg'
static const uint8_t tiBug[] =
{
0x42, // Image width in pixels
0x08, // Image height in rows (1 row = 8 pixels)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x08, 0x00, 0x00, 0x0f, 0xcf, 0xcf, 0xcf, 0xcf,
0xcf, 0xc8, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xc0, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x70, 0x7c, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x01, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x01, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0,
0xf0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x80, 0x00, 0x0e, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfc, 0x80, 0x00, 0x0e, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
0x80, 0x80, 0xc0, 0xc0, 0xf0, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, 0x03, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0xfe,
0xfc, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xe0, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xc0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void main(void)
{
uint8_t contrast = *((unsigned char *)contrastSetpointAddress); //读取FLASH中对比度值
uint8_t brightness = *((unsigned char *)brightnessSetpointAddress); //读取FLASH中背光值
// Initialize accelerometer offset from flash
Cma3000_setAccel_offset(*((unsigned char *)accelXcalibrationAddress), //初始化加速度偏移量
*((unsigned char *)accelYcalibrationAddress),
*((unsigned char *)accelZcalibrationAddress));
// Stop WDT
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
// Basic GPIO initialization
Board_init(); //初始化GPIO
// Set Vcore to accomodate for max. allowed system speed
SetVCore(3); //设VCore为最大
// Use 32.768kHz XTAL as reference
LFXT_Start(XT1DRIVE_0); //利用LFXT1(32.768kHZ)作为时钟参考
// Set system clock to max (25MHz)
Init_FLL_Settle(25000, 762); //利用FLL(锁频环)将系统时钟设为最大25MHZ
SFRIFG1 = 0; //清中断标志
SFRIE1 |= OFIE; //使能晶振失效中断
// Globally enable interrupts
__enable_interrupt(); //使能全局中断
// Setup real time clock
//SetupRTC(); //设置实时时钟
// Set up LCD
Dogs102x6_init(); //初始化LCD
Dogs102x6_backlightInit(); //背光初始化
// Contrast not programed in Flash Yet
if (contrast == 0xFF) //若当前FLASH中无对比度值,则将对比度值设为11(默认)
// Set Default Contrast
contrast = 11;
// Brightness not programed in Flash Yet
if (brightness == 0xFF) //若当前FLASH中无背光值,则将背光值设为11(默认)
// Set Default Brightness
brightness = 11;
Dogs102x6_setBacklight(brightness); //设置初始背光值
Dogs102x6_setContrast(contrast); //设置初始对比度值
Dogs102x6_clearScreen(); //清屏
// Set up wheel
Wheel_init(); //初始化齿轮电位计
Buttons_init(BUTTON_ALL); //初始化按键
Buttons_interruptEnable(BUTTON_ALL); //使能所有按键中断
buttonsPressed = 0; //键值清零
// Display TI logo
Dogs102x6_imageDraw(tiBug, 0, 16); //显示TI图案
// Wait for button press
while (!buttonsPressed) //等待按键被按下,或者超时退出等待
{
for (timeoutCounter = 0; timeoutCounter < 0xFFFF; timeoutCounter++)
{
if (buttonsPressed)
break;
__delay_cycles(1000);
}
//Timeout break
break; //超时退出
}
Dogs102x6_clearScreen();
buttonsPressed = 0;
//显示文字说明:
Dogs102x6_stringDraw(3, 0, " Welcome to ", DOGS102x6_DRAW_NORMAL);
Dogs102x6_stringDraw(4, 0, " MSP-EXP430F5529 ", DOGS102x6_DRAW_NORMAL);
Dogs102x6_stringDraw(6, 0, "Wait for a moment", DOGS102x6_DRAW_INVERT);
Dogs102x6_stringDraw(7, 0, "or press S1 | S2 ", DOGS102x6_DRAW_INVERT);
// Wait for button press
while (!buttonsPressed) //等待按键被按下,或者超时退出等待
{
for (timeoutCounter = 0; timeoutCounter < 0xFFFF; timeoutCounter++)
{
if (buttonsPressed)
break;
__delay_cycles(2000);
}
//Timeout break
break;
}
Dogs102x6_clearScreen();
// 主循环
while (1)
{
lab(); //试验程序
}
}
2.lab()函数
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "msp430.h"
#include "HAL_PMM.h"
#include "HAL_UCS.h"
#include "HAL_Buttons.h"
#include "HAL_Dogs102x6.h"
#include "HAL_Board.h"
#include "HAL_Menu.h"
#include "HAL_Wheel.h"
#include "MassStorage.h"
#include "mouse.h"
#include "descriptors.h"
#include "usb.h" // USB-specific functions
#include "UsbCdc.h"
#include "Demo_Cube.h"
#include "CTS_Layer.h"
#include "LaunchpadDef.h"
#include "Random.h"
#define LAC 10
#define JA 15
void showTime(uint8_t d1 ,uint8_t d2 ,uint8_t d3 ,uint8_t d4 ,uint8_t d5 ,uint8_t d6);
void timingCloseLED();
void shining(uint8_t where, uint8_t what,uint8_t stage);
void countDowm(uint8_t *what);
char aTo1(uint8_t what);
//static uint8_t stage = 0;
static const uint8_t hour[] =
{//宽高
0x0c,
0x02, //即是说,一个中文字符,高0x02,宽0x0c
//从汉子生成软件之中的拷贝来的数据,宽高:12X12
0x7F,0x44,0x44,0x7F,0x00,0x10,0x12,0x11,0x10,0xFF,0x10,0x00,0xE0,0x40,
0x40,0xE0,0x00,0x00,0x00,0x90,0x10,0xF0,0x00,0x00,/*"时",0*/
};
static const uint8_t minute[] =
{//宽高
0x0c,
0x02, //即是说,一个中文字符,高0x02,宽0x0c
//从汉子生成软件之中的拷贝来的数据,宽高:12X12
0x04,0x08,0x34,0xC4,0x07,0x04,0x04,0xC4,0x37,0x08,0x04,0x00,0x00,0x10,
0x20,0xC0,0x00,0x10,0x10,0x10,0xE0,0x00,0x00,0x00,/*"分",0*/
};
static const uint8_t second[] =
{//宽高
0x0c,
0x02, //即是说,一个中文字符,高0x02,宽0x0c
//从汉子生成软件之中的拷贝来的数据,宽高:12X12
0x48,0x4B,0x7F,0x89,0x02,0x1C,0x00,0xFF,0x00,0x20,0x1D,0x00,0x80,0x00,
0xF0,0x00,0x10,0x10,0x20,0x20,0x40,0x80,0x00,0x00,/*"秒",0*/
};
void lab(void)
{
buttonsPressed = 0;
//The countdown设置倒计时
Dogs102x6_stringDraw(2, 4, " Welcome to the countdowm " ,DOGS102x6_DRAW_NORMAL);
Dogs102x6_stringDraw(3, 0, " Press the Button s1 or" ,DOGS102x6_DRAW_NORMAL);
Dogs102x6_stringDraw(4, 0, "s2 to set the countdowm!" ,DOGS102x6_DRAW_NORMAL);
// Wait for button press
while (!buttonsPressed) //等待按键被按下,或者超时退出等待
{
__delay_cycles(1000000);
}
Dogs102x6_clearScreen();
buttonsPressed = 0;
//进入倒计时设定界面,一个一个的设定字符
// uint8_t isOK = 0;/
uint8_t where = 0;//0~5
uint8_t what[6] = {0};//0~9
uint8_t or = where;
//uint8_t sliderPosition = 0;
//uint8_t selection = 0;//选择
Dogs102x6_charDraw(3, LAC,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+6,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(hour, 3,LAC+JA);
Dogs102x6_charDraw(3, LAC+JA*2,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+JA*2+6,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(minute, 3,LAC+JA*3);
Dogs102x6_charDraw(3, LAC+JA*4,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+JA*4+6,'0', DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(second, 3,LAC+JA*5);
/**
* 改成:
* 先用齿轮确定要设定的位置
* 再用s1确认
* 接着进入加减,使用齿轮
* 用s1确认
* 在使用齿轮确定要设定的位置
*
* 安s2确认设定完成break
*/
Dogs102x6_stringDraw(5,0,"Press s2 to make true.",0);
while(1){
//确定齿轮电位计的位置
if(Wheel_getPosition()>=0&&Wheel_getPosition()<=5)where = Wheel_getPosition();
shining(where,what[where],1);//该位置反色
if(or != where){
shining(or,what[or],0);
or = where;
}
//再用s1确认,接着进入加减,使用齿轮
if(buttonsPressed & BUTTON_S1){
buttonsPressed = 0;
Dogs102x6_stringDraw(5,0,"Press s1 to make true.",0);
while(1){
// __delay_cycles(50000000);//延时,微秒
if(Wheel_getValue()/100>=0&&Wheel_getValue()/100<=9)
what[where] = Wheel_getValue()/100;
shining(where,what[where],1);//该位置反色
if(buttonsPressed & BUTTON_S1){
buttonsPressed = 0;
break;
}
}
}
Dogs102x6_stringDraw(5,0,"Press s2 to make true.",0);
if(buttonsPressed & BUTTON_S2){
buttonsPressed = 0;
Dogs102x6_clearScreen();
Dogs102x6_stringDraw(3,0,"Do you want to quit?",0);
Dogs102x6_stringDraw(4,0,"(yes:press s2;no:press s1)",0);
if(buttonsPressed & BUTTON_S2){
buttonsPressed = 0;
Dogs102x6_clearScreen();
break;
}
// else if(buttonsPressed & BUTTON_S1){
// buttonsPressed = 0;
// Dogs102x6_clearScreen();
// showTime(what[0],what[1],what[2],what[3],what[4],what[5]);
// Dogs102x6_stringDraw(5,0,"Press s2 to make true.",0);
// continue;
// }
}
}
// uint8_t a[6] = {0,0,1,1,1,1};
countDowm(what);
// countDowm(a);
}
//显现倒计时时间,是设置时间之后的
void showTime(uint8_t d1 ,uint8_t d2 ,uint8_t d3 ,uint8_t d4 ,uint8_t d5 ,uint8_t d6){
char h1,h2,m1,m2,s1,s2;
h1 = aTo1(d1);
h2 = aTo1(d2);
m1 = aTo1(d3);
m2 = aTo1(d4);
s1 = aTo1(d5);
s2 = aTo1(d6);
Dogs102x6_charDraw(3, LAC,h1, DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+6,h2, DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(hour, 3,LAC+JA);
Dogs102x6_charDraw(3, LAC+JA*2,m1, DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+JA*2+6,m2, DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(minute, 3,LAC+JA*3);
Dogs102x6_charDraw(3, LAC+JA*4,s1, DOGS102x6_DRAW_NORMAL);
Dogs102x6_charDraw(3, LAC+JA*4+6,s2, DOGS102x6_DRAW_NORMAL);
Dogs102x6_imageDraw(second, 3,LAC+JA*5);
}
//开始倒计时
void countDowm(uint8_t *what){
int h1,h2,m1,m2,s1,s2;
int time = (what[0]*10+what[1])*3600+(what[2]*10+what[3])*60+what[4]*10+what[5];//以秒为单位
h1 = what[0];
h2 = what[1];
m1 = what[2];
m2 = what[3];
s1 = what[4];
s2 = what[5];
while(time>0||(h1<=0&&
h2<=0&&m1<=0&&
m2<=0&&s1<=0&&
s2<=0)){
showTime(h1,h2,m1,m2,s1,s2);
__delay_cycles(50000000);//延时,微秒
time--;
s2--;
if(s2<0){
s2 = 9;
s1--;
}
if(s1<0){
s1 = 5;
m2--;
}
if(m2<0){
m2 = 9;
m1--;
}
if(m1<0){
m1 = 5;
h2--;
}
if(h2<0){
h2 = 9;
h1--;
}
if(h1<0){
h1 = 0;
}
}
uint8_t flag = 0;
Dogs102x6_clearScreen();
while(!buttonsPressed){
if(flag==0){
Board_ledOn(LED_ALL);
flag = 1;
}else if(flag==1){
Board_ledOff(LED_ALL);
flag = 0;
}
Dogs102x6_stringDraw(3,0," Time is out!",0);
__delay_cycles(1000000);//延时,微秒
}
Board_ledOff(LED_ALL);
Dogs102x6_clearScreen();
}
//显现闪现的数字,参数:第几个位置闪现,闪现的数值
void shining(uint8_t where, uint8_t wha,uint8_t stage){
char what = aTo1(wha);
switch(where){
case 0:
Dogs102x6_charDraw(3, LAC,what, stage);
break;
case 1:
Dogs102x6_charDraw(3, LAC+6,what, stage);
break;
case 2:
Dogs102x6_charDraw(3, LAC+JA*2,what, stage);
break;
case 3:
Dogs102x6_charDraw(3, LAC+JA*2+6,what, stage);
break;
case 4:
Dogs102x6_charDraw(3, LAC+JA*4,what, stage);
break;
case 5:
Dogs102x6_charDraw(3, LAC+JA*4+6,what, stage);
break;
default:
break;
}
//if(stage==0)
//stage=1;
//else if(stage==1)
//stage=0;
}
//定时熄灭LED,2秒
void timingCloseLED(){
__delay_cycles(2000);//延时,微秒
Board_ledOff(LED_ALL);
}
//字符与数值的转换
char aTo1(uint8_t what){
switch(what){
case 0:
return '0';
case 1:
return '1';
case 2:
return '2';
case 3:
return '3';
case 4:
return '4';
case 5:
return '5';
case 6:
return '6';
case 7:
return '7';
case 8:
return '8';
case 9:
return '9';
}
}
<!--EndFragment--><!--EndFragment-->