本代碼需要注意的細節
- 每次字符串的發送時間至少間隔三秒,發送的字符的數量最好在32個以內,防止數據接收不全。
- 本代碼波特率的設置爲1200.如果波特率設置過高,會出現數據接收不全的問題。我試過9600的波特率,會出現問題。讀者可以自行修改代碼,實現更高的傳輸速率。
- 有關的細節會在代碼中說明
代碼實現
主函數
#include <msp430f169.h>
#include "Config.h"
#include "LCD.h"
#include "Init.h"
#include "UART.h"
//#include "stdlib.h" 本來想用全局指針來存儲接收的數據
// 結果發現自己用不來........
//#include "string.h"
//unsigned char a[60];
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看門狗
Clock_Init(); //系統時鐘設置
LCD_Port_init(); //LCD IO初始化
delay_ms(100); //延時100ms,
LCD_init(); //液晶參數初始化設置
LCD_clear(); //清屏
UART_Init(); //串口設置初始化
_EINT(); //開中斷
Print_Str("DM430-L Board UART Test...\n");//發送字符串測試,使用串口助手顯示
while(1)
{
LPM0; //採用低功耗模式接收中斷
}
}
UART.C配置
/*
* UART.c
*
* Created on: 2020年4月20日
* Author: qq_rowosr
*/
#include "UART.h"
#include "stdlib.h"
//#include "string.h"
//#include "LCD.h"
//extern unsigned char a[60];
//串口初始化
void UART_Init()
{
U0CTL|=SWRST + CHAR; //復位SWRST,8位數據模式
U0TCTL|=SSEL1; //SMCLK爲串口時鐘
U0BR1=0X1A; //BRCLK=8MHZ,Baud=BRCLK/N
U0BR0=0X0A; //N=UBR+(UxMCTL)/8
U0MCTL=0x00; //微調寄存器爲0,波特率1200bps
ME1|=UTXE0; //UART0發送使能
ME1|=URXE0; //UART0接收使能
U0CTL&=~SWRST;
IE1|=URXIE0; //接收中斷使能位
P3SEL|= BIT4 + BIT5; //設置IO口爲第二功能模式,啓用UART功能
P3DIR|= BIT4; //設置TXD0口方向爲輸出
}
void Send_Byte(uchar data)
{
while(!(IFG1&UTXIFG0)); //發送寄存器空的時候發送數據
U0TXBUF=data;
}
//*************************************************************************
// 串口0發送字符串函數
//*************************************************************************
void Print_Str(uchar *s)
{
while(*s != '\0')
{
Send_Byte(*s++);
}
}
//**************************************
// 中斷函數
//**************************************
#pragma vector=USART0RX_VECTOR
__interrupt void UART0_RX_ISR(void)
{
LPM0_EXIT; //退出低功耗
uchar data = 0;
data = U0RXBUF; //接收到的數據存起來
Send_Byte (data); //將接收到的數據再發送出去
Display_Character_String(data); //在1602顯示接收的字符
}
UART.h
/*
* UART.h
*
* Created on: 2020年4月20日
* Author: QQ_rowosr
*/
#ifndef UART_H_
#define UART_H_
#include <msp430f169.h>
#include "Config.h"
void Print_Str(uchar *s);
void Send_Byte(uchar data);
void UART_Init();
#endif /* UART_H_ */
LCD.h
/*
* 1602.h
*
* Created on: 2020年4月20日
* Author: QQ_rowosr
*/
#ifndef LCD_H_
#define LCD_H_
#include <msp430f169.h>
#include "Config.h"
void LCD_Port_init();
void LCD_write_com(unsigned char com);
void LCD_write_data(unsigned char data);
void LCD_clear(void);
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s);
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data);
void LCD_init(void);
void Display_Character_String(unsigned char data);
#endif /* 1602_H_ */
LCD.c
/*
* 1602.c
*
* Created on: 2020年4月20日
* Author: QQ_rowosr
*/
#include "LCD.h"
//*************************************************************************
// 初始化IO口子程序
//*************************************************************************
void LCD_Port_init()
{
P4SEL = 0x00;
P4DIR = 0xFF; //數據口輸出模式
P5SEL = 0x00;
P5DIR |= BIT5 + BIT6 + BIT7; //控制口設置爲輸出模式
}
//***********************************************************************
// 顯示屏命令寫入函數
//***********************************************************************
void LCD_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com; //命令寫入端口
delay_us(100);
EN_CLR;
}
//***********************************************************************
// 顯示屏數據寫入函數
//***********************************************************************
void LCD_write_data(unsigned char data)
{
RS_SET;
RW_CLR;
EN_SET;
DataPort = data; //數據寫入端口
delay_us(100);
EN_CLR;
}
//***********************************************************************
// 顯示屏清空顯示
//***********************************************************************
void LCD_clear(void)
{
LCD_write_com(0x01); //清屏幕顯示
delay_ms(5);
}
//***********************************************************************
// 顯示屏字符串寫入函數
//***********************************************************************
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_write_com(0x80 + x); //第一行顯示
}
else
{
LCD_write_com(0xC0 + x); //第二行顯示
}
while (*s)
{
LCD_write_data( *s);
s ++;
}
}
//***********************************************************************
// 顯示屏單字符寫入函數
//***********************************************************************
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
if (y == 0)
{
LCD_write_com(0x80 + x); //第一行顯示
}
else
{
LCD_write_com(0xC0 + x); //第二行顯示
}
LCD_write_data( data);
}
//***********************************************************************
// 顯示屏初始化函數
//***********************************************************************
void LCD_init(void)
{
LCD_write_com(0x38); //顯示模式設置
delay_ms(5);
LCD_write_com(0x08); //顯示關閉
delay_ms(5);
LCD_write_com(0x01); //顯示清屏
delay_ms(5);
LCD_write_com(0x06); //顯示光標移動設置
delay_ms(5);
LCD_write_com(0x0C); //顯示開及光標設置
delay_ms(5);
}
//************************************
// 字符串顯示函數
//***********************************
void Display_Character_String(unsigned char data)
{
static int i = 0;
static int y = 0;
if (i % 2 == 0) //第一行顯示
{
LCD_write_com (0x80 + y);
LCD_write_data (data);
y++;
if (y == 16){ i++;y = 0;}
}
else //第二行顯示
{
LCD_write_com (0xc0 + y);
LCD_write_data (data);
y++;
if (y == 16)
{
i++ ;
y = 0;
delay_ms(1000); //讀者可以自行設置延時時間,但是兩次發送字符串的間隔時間,大於你設置的延時時間
LCD_clear(); //接收到32個字符,清屏
}
}
}
Config.h
/*
* Config.h
*
* Created on: 2020年4月20日
* Author: QQ_rowosr
*/
#ifndef CONFIG_H_
#define CONFIG_H_
#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
//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 /* CONFIG_H_ */
Init.h
/*
* Init.h
*
* Created on: 2020年4月20日
* Author: QQ_rowosr
*/
#ifndef INIT_H_
#define INIT_H_
#include <msp430f169.h>
#include "Config.h"
void Clock_Init_Inc()
{
uchar i;
// 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;
}
//***********************************************************************
// 系統時鐘初始化,外部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++)
_NOP();
}
while((IFG1&OFIFG)!=0); //如果標誌位1,則繼續循環等待
IFG1&=~OFIFG;
}
#endif /* INIT_H_ */