仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
快照1.jpg (90.47 KB, 下載次數: 64)
下載附件
LCD1602顯示系統真實時鐘
2021-10-7 14:18 上傳
單片機源程序如下:
#include "stm32f10x.h"
void LCD1602_GPIO_Config(void)
{
RCC_APB2PeriphClockCmd(LCD1602_CLK, ENABLE);
GPIO_InitTypeDef LCD1602_GPIOStruct;
LCD1602_GPIOStruct.GPIO_Mode = GPIO_Mode_Out_PP;
LCD1602_GPIOStruct.GPIO_Speed = GPIO_Speed_10MHz;
LCD1602_GPIOStruct.GPIO_Pin = LCD1602_E | LCD1602_RS | LCD1602_RW ;
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
//LCD1602_GPIOStruct.GPIO_Mode = GPIO_Mode_Out_OD;
LCD1602_GPIOStruct.GPIO_Pin = DB0 | DB1 | DB2 |DB3 | DB4 | DB5|
DB6 | DB7 ; //若設置為開漏輸出 需要上拉電阻
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
}
void LCD1602_WaitReady(void) //檢測忙狀態
{
uint8_t sta;
LCD1602_GPIO_PORT->ODR =0x00FF;
RSO(0);
RWO(1);
EO(1);
SysTick_Delay_Us(1);
do{
sta=GPIO_ReadInputDataBit(LCD1602_GPIO_PORT,GPIO_Pin_7);
EO(0);
}while(sta);
}
void LCD1602_WriteCmd(uint8_t cmd) //寫指令
{
LCD1602_WaitReady();
RSO(0);
RWO(0);
EO(0);
SysTick_Delay_Us(1);
EO(1);
LCD1602_GPIO_PORT->ODR &= (cmd|0xFF00);
EO(0);
SysTick_Delay_Us(400);
}
void LCD1602_WriteDat(uint8_t dat) //寫數據
{
LCD1602_WaitReady();
RSO(1);
RWO(0);
SysTick_Delay_Us(30);
EO(1);
LCD1602_GPIO_PORT->ODR &=(dat|0xFF00);
EO(0);
SysTick_Delay_Us(400);
}
void LCD1602_SetCursor(uint8_t x, uint8_t y)
{
uint8_t addr;
if (y == 0) //由輸入的屏幕坐標計算顯示RAM的地址
addr = 0x00 + x; //第一行字符地址從0x00起始
else
addr = 0x40 + x; //第二行字符地址從0x40起始
LCD1602_WriteCmd(addr|0x80); //設置RAM地址
}
void LCD1602_ShowStr(uint8_t x, uint8_t y, uint8_t *str, uint8_t len)
{
LCD1602_SetCursor(x, y); //設置起始地址
while (len--) //連續寫入len個字符數據
{
LCD1602_WriteDat(*str++);
}
}
void LCD1602_Init(void)
{
LCD1602_GPIO_Config(); //開啟GPIO口
LCD1602_WriteCmd(0X38); //16*2顯示,5*7點陣,8位數據接口
LCD1602_WriteCmd(0x0C); //顯示器開,光標關閉
LCD1602_WriteCmd(0x06); //文字不動,地址自動+1
LCD1602_WriteCmd(0x01); //清屏
}
int main(void)
{ uint8_t str[8];
RCC_ClocksTypeDef RCC_Clocks; //時鐘結構體
SysTick_Init(); //滴答定時器初始化
LCD1602_Init();
RCC_GetClocksFreq(&RCC_Clocks); //獲取片上時鐘
str[0]=RCC_Clocks.SYSCLK_Frequency/10000000+0x30;
str[1]=RCC_Clocks.SYSCLK_Frequency/1000000%10+0x30;
LCD1602_ShowStr(0,0,"sysclk:",7);
LCD1602_ShowStr(7,0,str,2);
LCD1602_ShowStr(9,0,"MHz",3);
while(1);
}
void SysTick_Delay_Us( __IO uint32_t us) //us延時函數
{
uint32_t i;
RCC_GetClocksFreq(&RCC_Clocks); //獲取片上真實系統時鐘
SysTick_Config(RCC_Clocks.SYSCLK_Frequency/1000000);
for(i=0;i<us;i++)
{
// 當計數器的值減小到0的時候,CRTL寄存器的位16會置1
while( !((SysTick->CTRL)&(1<<16)) );
}
// 關閉SysTick定時器
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_Ms( __IO uint32_t ms) // ms延時函數
{
uint32_t i;
RCC_GetClocksFreq(&RCC_Clocks); //獲取片上真實系統時鐘
SysTick_Config(RCC_Clocks.SYSCLK_Frequency/1000);
for(i=0;i<ms;i++)
{
// 當計數器的值減小到0的時候,CRTL寄存器的位16會置1
// 當置1時,讀取該位會清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 關閉SysTick定時器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
51hei.png (7.11 KB, 下載次數: 59)
下載附件
2021-10-7 14:55 上傳
全部資料51hei附件下載:
滴答定時器LCD1602仿真代碼.7z
(189.71 KB, 下載次數: 102)
2021-10-7 14:55 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|