在学习单片机课设“篮球比赛电子计分牌”的时候遇到了很多问题。在网上搜索到的资源很杂很乱,很多内容都需要付费,在学习的过程遇到了不少的阻力,因此我打算把我所做的拿出来与大家共同讨论,不足的地方还请多多指教哈。学艺不精,成绩仅为良好,大家参考就行。另外能激发后人的动手能力,不涉及抄袭,我只拿出来一部分(狗头)。**
一、课程设计内容
根据篮球比赛的计分规则,设计篮球比赛计分牌,具体内容如下:
1.用LCD显示屏显示比赛双方比赛和计分信息;
2.制定计分标准,有得1分、2分和3分的情况,加、减分及显示功能利用矩阵键盘实现;
3.有倒计时时钟显示,“暂停时间到”和“比赛时间到”时发出声光提示。
以上是课设要求。使用Protues版本为8.17和keil5,实验箱为Lab8000。(沈航学子用的是这个)
本次课程设计硬件部分主要运用到51单片机、LM1602L模块、矩阵键盘模块硬件。通过矩阵键盘输入、单片机系统处理、LCD模块输出实现整个目标。单矩阵键盘连接单片机P1口,通过扫描P1口高低电平的交替变化来确认按下的是哪一个键然后执行该键说指功能。LCD显示模块连接单片机P0口,通过P0口输出信息给LM1602L显示。P2口连接38译码器使用,选择内驱连接。
实验电路图如下图所示。(这个博客排版我也不是很会,大家凑合看吧)
这个电路图是平时7次实验改编过来的,认真做实验一定能画出来,这里选择实验箱中的内驱。(外驱老师说比较难)
这个课设难的地方主要是LCD显示。是好几个同学共同研究出来的,方便后人学习,我分享给大家。
// 函数声明
void LCD_Init(void);
void LCD_Command(unsigned char cmd);
void LCD_WriteChar(unsigned char xta);
void LCD_WriteString(char *str);
void lcd16_set_cursor(unsigned char row, unsigned char col);
void lcd16_data(unsigned char val);
// LCD 初始化函数
void LCD_Init(void)
{
// 设置为8位模式,2行,5x7点阵字符
LCD_Command(0x38);
delay(10);
// 打开显示,关闭光标
LCD_Command(0x0C);
delay(10);
// 清屏
LCD_Command(0x01);
delay(10);
// 设置光标移动方向
LCD_Command(0x06);
delay(10);
LCD_Command(0x18);
delay(10);
}
// 发送命令到LCD
void LCD_Command(unsigned char cmd)
{
// 写入命令
*((unsigned char xdata *)LCD_BASE_ADDRESS) = cmd;
// 产生使能脉冲
delay(1);
}
// 发送数据到LCD
void LCD_WriteChar(unsigned char xta)
{
// 写入数据
*((unsigned char xdata *)LCD_Data_ADDRESS) = xta;
// 产生使能脉冲
delay(1);
}
// 发送字符串到LCD
void LCD_WriteString(char *str)
{
while (*str)
{
LCD_WriteChar(*str++);
}
}
void lcd16_data(unsigned char val)
{
*((unsigned char xdata *)LCD_Data_ADDRESS) = val; // 将数据写入数据端
delay(2);
}
void lcd16_set_cursor(unsigned char row, unsigned char col)
{
unsigned char address;
if (row == 0)
{
address = col; // 第一行
}
else
{
address = 0x40 + col; // 第二行
}
LCD_Command(0x80 + address); // 设置DDRAM地址命令 (0x80 | address)
}
这个代码应该也是同学们在网上搜罗研究出来的,如有侵权联系我哈。这是整个课设最关键的一步,能让LCD点亮。再次之前我也在网络上搜寻到另一版本代码,但是仿真能跑通,实验箱上就不对。
主函数调用就是这样哒
void main(void)
{
TMOD |= 0X01; // 3?ê??ˉ?¨ê±?÷
TH0 = 0X3C;
TL0 = 0XB0;
ET0 = 1; // ′ò?a?¨ê±?÷0?D???êDí
EA = 1; // ′ò?a×ü?D??
TR0 = 1; // ′ò?a?¨ê±?÷
while (1)
{
LCD_Init(); // 初始化LCD
while (1)
{
lcd16_set_cursor(0, 0);
B_scan();
lcd16_data('0' + fen / 10);
lcd16_data('0' + fen % 10);
LCD_WriteString(":");
lcd16_data('0' + miao / 10);
lcd16_data('0' + miao % 10);
LCD_WriteString("TeamA:");
lcd16_data('0' + score1[0]);
lcd16_data('0' + score1[1]);
lcd16_data('0' + score1[2]);
lcd16_set_cursor(1, 0);
// lcd16_data('0' +team);
LCD_WriteString(" ");
LCD_WriteString("TeamB:");
lcd16_data('0' + point1[0]);
lcd16_data('0' + point1[1]);
lcd16_data('0' + point1[2]);
if (sks == 0)
{
}
else
{
sks = 0;
temp1 = fen;
temp2 = miao;
fen = 00;
miao = 10;
}
}
}
}
这里面的B_scan()函数就是扫描键盘。很重要但是不难。
其余代码就是实现各个逻辑功能啦,很简单,就不放出来了,留给大家自己探索哈。运行结果就是这样的: