PHẦN 3. XÂY DỰNG THIẾT KẾ HỆ THỐNG
IV. Sơ đồ thiết kế mạch
V. Viết chương trình code cho vi điều khiển STM32F103C8T6 File delay.c
#include "delay.h"
void Delay_Init(void) {
/* su dung timer nao do de tao delay */
TIM_TimeBaseInitTypeDef timInit;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
timInit.TIM_ClockDivision = TIM_CKD_DIV1;
timInit.TIM_CounterMode = TIM_CounterMode_Up;
timInit.TIM_Period = 0xffff;
timInit.TIM_Prescaler = 72 - 1;
timInit.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timInit);
TIM_Cmd(TIM2, ENABLE);
}
void delay_ms(uint32_t u32Delay) {
uint32_t i;
for (i = 0; i< u32Delay; ++i) { delay_us(1000);
} }
void delay_us(uint32_t u32Delay)
{
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < u32Delay);
} File delay.h
#ifndef DELAY_H_
#define DELAY_H_
#include "stm32f10x.h"
void Delay_Init(void);
void delay_ms(uint32_t u32Delay);
void delay_us(uint32_t u32Delay);
#endif File dht11.c
#include "dht11.h"
#include "delay.h"
void dht11_init(void) {
GPIO_InitTypeDef gpioInit;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
gpioInit.GPIO_Mode = GPIO_Mode_Out_OD;
gpioInit.GPIO_Pin = GPIO_Pin_8; // chan data cua DHT11 noi voi chan PB8 cua STM32
GPIO_Init(GPIOB, &gpioInit);
GPIO_SetBits(GPIOB, GPIO_Pin_8);
}
uint8_t dht11_read(uint8_t *pu8Data) {
uint16_t u16Tim;
uint8_t u8Buff[5];
uint8_t u8CheckSum;
uint8_t i;
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
delay_ms(20);
GPIO_SetBits(GPIOB, GPIO_Pin_8);
/* cho chan PB12 len cao */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 10) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} } u16Tim =
TIM_GetCounter(TIM2); if (u16Tim >= 10) {
return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 45) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 45) || (u16Tim <= 5)) { return 0;
}
/* cho chan PB12 len cao */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 90) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 90) || (u16Tim <= 70)) { return 0;
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 95) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 95) || (u16Tim <= 75)) { return 0;
}
/* nhan byte so 1 */
for (i = 0; i < 8; ++i) {
/* cho chan PB12 len cao */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 65) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 65) || (u16Tim <= 45)) { return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 80) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 80) || (u16Tim <= 10)) { return 0;
}
u8Buff[0] <<= 1;
if (u16Tim > 45) { /* nhan duoc bit 1 */
u8Buff[0] |= 1;
} else {
/* nhan duoc bit 0 */
u8Buff[0] &= ~1;
} }
/* nhan byte so 2 */
for (i = 0; i < 8; ++i) {
/* cho chan PB12 len cao */
while (TIM_GetCounter(TIM2) < 65) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 65) || (u16Tim <= 45)) { return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 80) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 80) || (u16Tim <= 10)) { return 0;
}
u8Buff[1] <<= 1;
if (u16Tim > 45) { /* nhan duoc bit 1 */
u8Buff[1] |= 1;
} else {
/* nhan duoc bit 0 */
u8Buff[1] &= ~1;
} }
/* nhan byte so 3 */
for (i = 0; i < 8; ++i) {
/* cho chan PB12 len cao */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 65) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 65) || (u16Tim <= 45)) { return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 80) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
}
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 80) || (u16Tim <= 10)) { return 0;
}
u8Buff[2] <<= 1;
if (u16Tim > 45) { /* nhan duoc bit 1 */
u8Buff[2] |= 1;
} else {
/* nhan duoc bit 0 */
u8Buff[2] &= ~1;
} }
/* nhan byte so 4 */
for (i = 0; i < 8; ++i) {
/* cho chan PB12 len cao */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 65) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 65) || (u16Tim <= 45)) { return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 80) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 80) || (u16Tim <= 10)) { return 0;
}
u8Buff[3] <<= 1;
if (u16Tim > 45) { /* nhan duoc bit 1 */
u8Buff[3] |= 1;
} else {
/* nhan duoc bit 0 */
u8Buff[3] &= ~1;
} }
/* nhan byte so 5 */
for (i = 0; i < 8; ++i) {
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 65) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 65) || (u16Tim <= 45)) { return 0;
}
/* cho chan PB12 xuong thap */
TIM_SetCounter(TIM2, 0);
while (TIM_GetCounter(TIM2) < 80) {
if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)) { break;
} }
u16Tim = TIM_GetCounter(TIM2);
if ((u16Tim >= 80) || (u16Tim <= 10)) { return 0;
}
u8Buff[4] <<= 1;
if (u16Tim > 45) { /* nhan duoc bit 1 */
u8Buff[4] |= 1;
} else {
/* nhan duoc bit 0 */
u8Buff[4] &= ~1;
} }
u8CheckSum = u8Buff[0] + u8Buff[1] + u8Buff[2] + u8Buff[3];
if (u8CheckSum != u8Buff[4]) { return 0;
}
for (i = 0; i < 4; ++i) { pu8Data[i] = u8Buff[i];
}
return 1;
}
File dht11.h
#ifndef DHT11_H_
#define DHT11_H_
#include "stm32f10x.h"
void dht11_init(void);
uint8_t dht11_read(uint8_t *pu8Data);
File i2c.c
#include <stm32f10x.h>
#include "delay.h"
#include "I2C.h"
void i2c_init(void) {
GPIO_InitTypeDef gpioInit;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
gpioInit.GPIO_Mode = GPIO_Mode_Out_OD;
gpioInit.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioInit);
SDA_1;
SCL_1;
}
void i2c_start(void) {
SCL_1;
delay_us(3);
SDA_1;
delay_us(3);
SDA_0;
delay_us(3);
SCL_0;
delay_us(3);
}
void i2c_stop(void) {
SDA_0;
delay_us(3);
SCL_1;
delay_us(3);
SDA_1;
delay_us(3);
}
uint8_t i2c_write(uint8_t u8Data) {
uint8_t i;
uint8_t u8Ret;
for (i = 0; i < 8; ++i) {
SDA_1;
} else { SDA_0;
} delay_us(3);
SCL_1;
delay_us(5);
SCL_0;
delay_us(2);
u8Data <<= 1;
}
SDA_1;
delay_us(3);
SCL_1;
delay_us(3);
if (SDA_VAL) {
u8Ret = 0;
} else { u8Ret = 1;
} delay_us(2);
SCL_0;
delay_us(5);
return u8Ret;
}
uint8_t i2c_read(uint8_t u8Ack) {
uint8_t i;
uint8_t u8Ret;
SDA_1;
delay_us(3);
for (i = 0; i < 8; ++i) { u8Ret <<= 1;
SCL_1;
delay_us(3);
if (SDA_VAL) {
u8Ret |= 0x01;
} delay_us(2);
SCL_0;
delay_us(5);
}
if (u8Ack) { SDA_0;
} delay_us(3);
SCL_1;
delay_us(5);
SCL_0;
delay_us(5);
return u8Ret;
}
void My_I2C_Init(void) {
i2c_init();
}
uint8_t I2C_Write(uint8_t Address, uint8_t *pData, uint8_t length) {
uint8_t i;
i2c_start();
if (i2c_write(Address) == 0) { i2c_stop();
return 0;
}
for (i = 0; i < length; ++i) { if (i2c_write(pData[i]) == 0) {
i2c_stop();
return 0;
} } i2c_stop();
return 1;
}
uint8_t I2C_Read(uint8_t Address, uint8_t *pData, uint8_t length) {
uint8_t i;
i2c_start();
if (i2c_write(Address) == 0) { i2c_stop();
return 0;
}
for (i = 0; i < length - 1; ++i) { pData[i] = i2c_read(1);
}
pData[i] = i2c_read(0);
return 1;
} File i2c.h
#ifndef I2C_H
#define I2C_H
#include "stm32f10x.h"
void My_I2C_Init(void);
uint8_t I2C_Write(uint8_t Address, uint8_t *pData, uint8_t length);
uint8_t I2C_Read(uint8_t Address, uint8_t *pData, uint8_t length);
extern void i2c_init(void);
extern void i2c_start(void);
extern void i2c_stop(void);
extern uint8_t i2c_write(uint8_t u8Data);
extern uint8_t i2c_read(uint8_t u8Ack);
#define SDA_0 GPIO_ResetBits(GPIOA, GPIO_Pin_0) // chan SDA cua i2c noi voi chan PA0 cua STM32
#define SDA_1 GPIO_SetBits(GPIOA, GPIO_Pin_0)
#define SCL_0 GPIO_ResetBits(GPIOA, GPIO_Pin_1) // chan SCL cua i2c noi voi chan PA1 cua STM32
#define SCL_1 GPIO_SetBits(GPIOA, GPIO_Pin_1)
#define SDA_VAL (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
#endif File i2c_lcd.c
#include "I2C.h"
#include "i2c_lcd.h"
static uint8_t u8LCD_Buff[8];//bo nho dem luu lai toan bo static uint8_t u8LcdTmp;
#define MODE_4_BIT 0x28
#define CLR_SCR 0x01
#define DISP_ON 0x0C
#define CURSOR_ON 0x0E
#define CURSOR_HOME 0x80
static void I2C_LCD_Write_4bit(uint8_t u8Data);
static void I2C_LCD_FlushVal(void);
static void I2C_LCD_WriteCmd(uint8_t u8Cmd);
void I2C_LCD_FlushVal(void) {
uint8_t i;
for (i = 0; i < 8; ++i) { u8LcdTmp >>= 1;
if(u8LCD_Buff[i]) { u8LcdTmp |= 0x80;
} }
I2C_Write(I2C_LCD_ADDR, &u8LcdTmp, 1);
}
{
uint8_t i;
I2C_LCD_Delay_Ms(50);
My_I2C_Init();
for (i = 0; i < 8; ++i) { u8LCD_Buff[i] = 0;
}
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RS] = 0;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RW] = 0;
I2C_LCD_FlushVal();
I2C_LCD_Write_4bit(0x03);
I2C_LCD_Delay_Ms(5);
I2C_LCD_Write_4bit(0x03);
I2C_LCD_Delay_Ms(1);
I2C_LCD_Write_4bit(0x03);
I2C_LCD_Delay_Ms(1);
I2C_LCD_Write_4bit(MODE_4_BIT >> 4);
I2C_LCD_Delay_Ms(1);
I2C_LCD_WriteCmd(MODE_4_BIT);
I2C_LCD_WriteCmd(DISP_ON);
I2C_LCD_WriteCmd(CURSOR_ON);
I2C_LCD_WriteCmd(CLR_SCR);
}
void I2C_LCD_Write_4bit(uint8_t u8Data) {
//4 bit can ghi chinh la 4 5 6 7 //dau tien gan LCD_E=1 //ghi du lieu //sau do gan LCD_E=0 if(u8Data & 0x08) {
u8LCD_Buff[LCD_D7] = 1;
} else {
u8LCD_Buff[LCD_D7] = 0;
}
if(u8Data & 0x04) {
u8LCD_Buff[LCD_D6] = 1;
} else {
u8LCD_Buff[LCD_D6] = 0;
}
if(u8Data & 0x02) {
u8LCD_Buff[LCD_D5] = 1;
} else {
u8LCD_Buff[LCD_D5] = 0;
}
if(u8Data & 0x01) {
u8LCD_Buff[LCD_D4] = 1;
} else {
}
u8LCD_Buff[LCD_EN] = 1;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_EN] = 0;
I2C_LCD_FlushVal();
}
void LCD_WaitBusy(void) {
char temp;
//dau tien ghi tat ca 4 bit thap bang 1 u8LCD_Buff[LCD_D4] = 1;
u8LCD_Buff[LCD_D5] = 1;
u8LCD_Buff[LCD_D6] = 1;
u8LCD_Buff[LCD_D7] = 1;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RS] = 0;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RW] = 1;
I2C_LCD_FlushVal();
do {
u8LCD_Buff[LCD_EN] = 1;
I2C_LCD_FlushVal();
I2C_Read(I2C_LCD_ADDR + 1, &temp, 1);
u8LCD_Buff[LCD_EN] = 0;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_EN] = 1;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_EN] = 0;
I2C_LCD_FlushVal();
} while (temp & 0x08);
}
void I2C_LCD_WriteCmd(uint8_t u8Cmd) {
LCD_WaitBusy();
u8LCD_Buff[LCD_RS] = 0;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RW] = 0;
I2C_LCD_FlushVal();
I2C_LCD_Write_4bit(u8Cmd >> 4);
void LCD_Write_Chr(char chr) {
LCD_WaitBusy();
u8LCD_Buff[LCD_RS] = 1;
I2C_LCD_FlushVal();
u8LCD_Buff[LCD_RW] = 0;
I2C_LCD_FlushVal();
I2C_LCD_Write_4bit(chr >>
4); I2C_LCD_Write_4bit(chr);
}
void I2C_LCD_Puts(char *sz) {
while (1) { if (*sz) {
LCD_Write_Chr(*sz++);
} else { break;
} } }
void I2C_LCD_Clear(void) {
I2C_LCD_WriteCmd(CLR_SCR);
}
void I2C_LCD_NewLine(void) {
I2C_LCD_WriteCmd(0xc0);
}
void I2C_LCD_BackLight(uint8_t u8BackLight) {
if(u8BackLight) {
u8LCD_Buff[LCD_BL] = 1;
} else {
u8LCD_Buff[LCD_BL] = 0;
}
I2C_LCD_FlushVal();
}
File i2c_lcd.h
#ifndef I2C_LCD_H_
#define I2C_LCD_H_
#include "stm32f10x.h"
#include "I2C.h"
#include <stdint.h>
#define I2C_LCD_ADDR 0x4E
extern void delay_ms(uint32_t u32DelayInMs);
#define LCD_EN 2
#define LCD_RW 1
#define LCD_RS 0
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
#define LCD_BL 3
void I2C_LCD_Init(void);
void I2C_LCD_Puts(char *szStr);
void I2C_LCD_Clear(void);
void I2C_LCD_NewLine(void);
void I2C_LCD_BackLight(uint8_t u8BackLight);
#endif File main.c
#include "stm32f10x.h"
#include "delay.h"
#include "dht11.h"
#include <stdio.h>
#include "i2c_lcd.h"
int main(void) {
GPIO_InitTypeDef gpioInit;
char szDisplay[17];
uint8_t u8Buff[4];
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_Init(GPIOC, &gpioInit);
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
gpioInit.GPIO_Pin = GPIO_Pin_14;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &gpioInit);
gpioInit.GPIO_Mode = GPIO_Mode_Out_PP;
gpioInit.GPIO_Pin = GPIO_Pin_0;
gpioInit.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioInit);
Delay_Init();
dht11_init();
i2c_init();
I2C_LCD_Init();
I2C_LCD_Clear();
I2C_LCD_BackLight(1);
I2C_LCD_Puts("STM32 & LCD1602");
I2C_LCD_NewLine();
I2C_LCD_Puts("STM32-DHT11");
delay_ms(5000);
I2C_LCD_Clear();
while (1) {
/* da doc duoc gia tri nhiet do va do am */
/* gui do am */
if (dht11_read(u8Buff)) { //send(u8Buff[0]);
sprintf(szDisplay, "Do am: %d ", u8Buff[0])
; I2C_LCD_Puts(szDisplay);
delay_ms(20);
//send(u8Buff[2]);
I2C_LCD_NewLine();
sprintf(szDisplay, "Nhiet do: %d ", u8Buff[2]);
I2C_LCD_Puts(szDisplay);
} else { // neu DHT11 bi loi
I2C_LCD_Clear();
I2C_LCD_Puts("STM32 - LCD1602");
I2C_LCD_NewLine();
I2C_LCD_Puts("DHT11: ERROR ");
}
if(u8Buff[2] >= 30)
{ GPIO_SetBits(GPIOC, GPIO_Pin_14);
delay_ms(500);
GPIO_ResetBits(GPIOC, GPIO_Pin_14);
delay_ms(500);
} } }