工具/软件:Code Composer Studio
你(们)好 我尝试使用 LCD 显示屏运行超声波传感器、以显示电流距离。 无论传感器前面是什么、我的结果都是0 cm。 请帮助我进行故障排除。 谢谢!
/******** //*
uC 和超声波传感器连接
P1.4 -触发
P1.5 -回波 */
******** //*
UC 和 LCD 连接
TP1 - Vcc (+5V)
TP3 - VSS (GND)
P2.2 -中文
P2.3 - RS
P2.4 - D4
P2.5 - D5.
P2.6 - D6
P2.7 - D7
GND - RW
GND - Ve/Vdd -通过1K 电阻器连接到 GND
-此值决定对比度-
即、如果没有电阻器、所有点始终可见、而是
-较高的电阻意味着根本不显示点。
接地- K (LED-)
VCC - A (LED+)+5V -用于背光
时钟:1MHz */
******** /#include
#include
#include
#include
// uC GPIO 端口分配
#define uC_port P2OUT
#define UC_PORT_DIR P2DIR
//外设引脚分配
#define US_TRIG BIT4
#define US_echo Bit5
#define LCD_EN Bit2
#define LCD_RS BIT3
#define LCD_DATA BIT4 | BIT4 | BIT6 | BIT4
#define LCD_D0_OFFSET 4 // BIT4,因此它是4
#define US_MASK US_TRIG | US_ECHO
#define LCD_MASK LCD_EN | LCD_RS | LCD_DATA
unsigned int up_counter;
unsigned int Distance_cm;
// Timer A0捕获中断例程
P1.1 (回波)会导致调用此例程*/
#pragma vector=TIMER0_A0_vector
__interrupt void TimerA0 (void)
{
IF (TA0CCTL0和 CCI) //上升沿
{
UP_COUNTER = TA0CCR0; //将计数器复制到变量
}
其他 //下降沿
{
//公式:以 cm 为单位的距离=(以 uec 为单位的时间)/58
Distance_cm =(TA0CCR0 - UP_COUNTER)/58;
}
TA0CCTL0 &=~CCIFG;
TA0CTL &=~TAIFG; //清除中断标志-已处理
}
void timer_init()
{
//将计时器 A0配置为读取回波信号:
Timer A 捕获/比较控制0 =>
捕捉模式:1 -双边沿+
捕获同步+
捕捉输入选择0 => P1.5 +
捕获模式+
捕获比较中断使能*/
TA0CCTL0 |= CM_3 + SCS + CCIS_0 + CAP + CCIE;
/* Timer A 控制配置=>
计时器 A 时钟源选择:1 - SMClock +
Timer A 模式控制:2 -连续运行+
Timer A 时钟输入分频器0 -无分频器*/
TA0CTL |= tassel_2 + MC_2 + ID_0;
//全局中断启用
_BIS_SR (GIE);
}
void LCD_reset ()
{
uC_port = 0x00;
_DELAY_CYCLES (20000);
uC_port =(0x03 << LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
_delay_cycles (10000);
uC_port =(0x03 << LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
_DELAY_CYCLES (1000);
uC_port =(0x03 << LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
_DELAY_CYCLES (1000);
uC_port =(0x02 << LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
__DELAY_CYCLES (1000);
}
void LCD_cmd (char cmd)
{
//发送上半字节
uC_port =((((cmd >> 4)& 0x0F)<< LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
//发送低位半字节
uC_port =((cmd & 0x0F)<< LCD_D0_offset)| LCD_EN;
uC_port &=~LCD_EN;
__delay_cycles (4000);
}
void LCD_data (unsigned char dat)
{
//发送上半字节
uC_port =((((dat >> 4)和0x0F)<< LCD_D0_offset)| LCD_EN | LCD_RS);
uC_port &=~LCD_EN;
//发送低位半字节
uC_port =(((dat 和0x0F)<< LCD_D0_offset)| LCD_EN | LCD_RS);
uC_port &=~LCD_EN;
__DELAY_CYCLES (4000);//较小的延迟可能会导致缺少字符显示
}
void LCD_init ()
{
LCD_RESET(); //调用 LCD 复位
LCD_cmd (0x28); // 4位模式- 2行- 5x7字体。
LCD_cmd (0x0C); //不显示光标-不闪烁。
LCD_cmd (0x06); //自动增量—无显示移位。
LCD_cmd (0x80); //地址 DDRAM、偏移量为80h。
LCD_cmd (0x01); //清除屏幕
}
void display_line (char *line)
{
while (*行)
LCD_DATA (*线++);
}
void display_distance (char *线、int len)
{
while (len-)
如果(*行)
LCD_DATA (*线++);
其他
lcd_data ('');
}
int main()
{
char Distance_string[4];
WDTCTL = WDTPW + WDTHOLD; //停止看门狗计时器
PM5CTL0 &=~LOCKLPM5;
uC_PORT_DIR = LCD_MASK; // LCD 连接的输出方向
P1DIR |= US_TRIG; //触发到传感器的输出方向
P1DIR &=~US_ECHO; //传感器回波的输入方向
P1DIR &=~US_TRIG; //将触发器保持在低电平
P1SEL1 = US_ECHO; //从端口1将 US_echo 设置为计时器的触发器
//初始化 LCD
lcd_init();
//初始化用于超声波距离感应的计时器
timer_init();
LCD_cmd (0x80);//选择第一行(0x80 + addr)-这里的 addr = 0x00
display_line ("距离计");
LCD_cmd (0xce);//选择第二行(0x80 + addr)-这里的 addr = 0x4e
display_line ("cm");
while (1)
{
//测量距离
P1OUT ^= US_TRIG; //断言
_DELAY_CYCLES (10); // 10us 宽
P1OUT ^= US_TRIG; //断言
//_delay_cycles (60000); // 60ms 测量周期
_delay_cycles (60000); // 0.5sec 测量周期
//显示当前距离
sprintf (distance 字符串、"%d"、distance cm);
LCD_cmd (0xcb);//选择第二行(0x80 + addr)-这里的 addr = 0x4b
Display_Distance (Distance_string、3);
}
}