- UID
- 373967
- 帖子
- 9008
- 主題
- 2609
- 精華
- 0
- 積分
- 1003
- 楓幣
- 0
- 威望
- 980
- 存款
- 35891
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 70
- 在線時間
- 460 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-12-22
|
製作自動咖啡機需要以下零件:
STM32F103C8T6 微控制器
16x2 字元 LCD 顯示器
4x4 矩陣按鈕
繼電器模組
NTC 溫度感測器
水位感測器
電磁閥
電熱水壺
杜邦線
麵包板
電源模組
以下是自動咖啡機的程式碼,供參考:
#include "stm32f10x.h"
#include "lcd.h"
#define BTN_PORT GPIOA
#define BTN_ROW_1 GPIO_Pin_0
#define BTN_ROW_2 GPIO_Pin_1
#define BTN_ROW_3 GPIO_Pin_2
#define BTN_ROW_4 GPIO_Pin_3
#define BTN_COL_1 GPIO_Pin_4
#define BTN_COL_2 GPIO_Pin_5
#define BTN_COL_3 GPIO_Pin_6
#define BTN_COL_4 GPIO_Pin_7
#define RELAY_PORT GPIOB
#define RELAY_PIN GPIO_Pin_0
#define TEMP_SENSOR_ADC ADC1
#define TEMP_SENSOR_CHANNEL ADC_Channel_16
#define WATER_LEVEL_ADC ADC1
#define WATER_LEVEL_CHANNEL ADC_Channel_17
#define WATER_VALVE_PORT GPIOB
#define WATER_VALVE_PIN GPIO_Pin_1
#define HEATER_PORT GPIOB
#define HEATER_PIN GPIO_Pin_2
void init_adc(void);
uint16_t read_adc(ADC_TypeDef* ADCx, uint8_t channel);
void init_gpio(void);
void init_relay(void);
void init_lcd(void);
void print_lcd(uint8_t row, uint8_t col, char *str);
void delay_ms(uint32_t ms);
int main(void)
{
uint16_t temp_adc_value;
uint16_t water_adc_value;
uint8_t brew_time = 0;
uint8_t brew_temp = 0;
uint8_t brew_strength = 0;
init_adc();
init_gpio();
init_relay();
init_lcd();
print_lcd(0, 0, "Select options:");
print_lcd(1, 0, "1.Time 2.Temp");
print_lcd(2, 0, "3.Strength 4.Brew");
while (1)
{
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_1) == 0)
{
delay_ms(50);
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_1) == 0)
{
brew_time++;
if (brew_time > 10)
{
brew_time = 1;
}
print_lcd(1, 5, " ");
print_lcd(1, 5, itoa(brew_time));
}
}
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_2) == 0)
{
delay_ms(50);
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_2) == 0)
{
brew_temp++;
if (brew_temp > 100)
{
brew_temp = 50;
}
print_lcd(1, 5, " ");
print_lcd(1, 5, itoa(brew_temp));
}
}
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_3) == 0)
{
delay_ms(50);
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_3) == 0)
{
brew_strength++;
if (brew_strength > 3)
{
brew_strength = 1;
}
print_lcd(2, 5, " ");
switch (brew_strength)
{
case 1:
print_lcd(2, 5, "Mild ");
break;
case 2:
print_lcd(2, 5, "Medium ");
break;
case 3:
print_lcd(2, 5, "Strong ");
break;
}
}
}
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_4) == 0)
{
delay_ms(50);
if (GPIO_ReadInputDataBit(BTN_PORT, BTN_ROW_4) == 0)
{
print_lcd(0, 0, "Brewing coffee...");
print_lcd(1, 0, "Temp:");
print_lcd(2, 0, "Strength:");
print_lcd(3, 0, "Time:");
print_lcd(1, 5, itoa(brew_temp));
switch (brew_strength)
{
case 1:
print_lcd(2, 5, "Mild ");
break;
case 2:
print_lcd(2, 5, "Medium ");
break;
case 3:
print_lcd(2, 5, "Strong ");
break;
}
print_lcd(3, 5, itoa(brew_time));
temp_adc_value = read_adc(TEMP_SENSOR_ADC, TEMP_SENSOR_CHANNEL);
water_adc_value = read_adc(WATER_LEVEL_ADC, WATER_LEVEL_CHANNEL);
if (temp_adc_value < brew_temp)
{
GPIO_SetBits(HEATER_PORT, HEATER_PIN);
}
else
{
GPIO_ResetBits(HEATER_PORT, HEATER_PIN);
}
if (water_adc_value > 100)
{
GPIO_SetBits(WATER_VALVE_PORT, WATER_VALVE_PIN);
}
else
{
GPIO_ResetBits(WATER_VALVE_PORT, WATER_VALVE_PIN);
}
GPIO_SetBits(RELAY_PORT, RELAY_PIN);
delay_ms(brew_time * 1000);
GPIO_ResetBits(RELAY_PORT, RELAY_PIN);
GPIO_ResetBits(WATER_VALVE_PORT, WATER_VALVE_PIN);
GPIO_ResetBits(HEATER_PORT, HEATER_PIN);
print_lcd(0, 0, "Select options:");
print_lcd(1, 0, "1.Time 2.Temp");
print_lcd(2, 0, "3.Strength 4.Brew");
}
}
}
}
void init_adc(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_ModeGPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_DeInit(TEMP_SENSOR_ADC);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(TEMP_SENSOR_ADC, &ADC_InitStructure);
ADC_Cmd(TEMP_SENSOR_ADC, ENABLE);
ADC_ResetCalibration(TEMP_SENSOR_ADC);
while (ADC_GetResetCalibrationStatus(TEMP_SENSOR_ADC))
;
ADC_StartCalibration(TEMP_SENSOR_ADC);
while (ADC_GetCalibrationStatus(TEMP_SENSOR_ADC))
;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_DeInit(WATER_LEVEL_ADC);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(WATER_LEVEL_ADC, &ADC_InitStructure);
ADC_Cmd(WATER_LEVEL_ADC, ENABLE);
ADC_ResetCalibration(WATER_LEVEL_ADC);
while (ADC_GetResetCalibrationStatus(WATER_LEVEL_ADC))
;
ADC_StartCalibration(WATER_LEVEL_ADC);
while (ADC_GetCalibrationStatus(WATER_LEVEL_ADC))
;
}
int read_adc(ADC_TypeDef *ADCx, uint8_t channel)
{
ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_28Cycles5);
ADC_SoftwareStartConvCmd(ADCx, ENABLE);
while (ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) == RESET)
;
return ADC_GetConversionValue(ADCx);
}
void init_lcd(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
lcd_send_cmd(0x33);
delay_us(50);
lcd_send_cmd(0x32);
delay_us(50);
lcd_send_cmd(0x28);
delay_us(50);
lcd_send_cmd(0x08);
delay_us(50);
lcd_send_cmd(0x01);
delay_ms(2);
lcd_send_cmd(0x06);
delay_us(50);
lcd_send_cmd(0x0C);
delay_us(50);
}
void lcd_send_cmd(uint8_t cmd)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
GPIO_ResetBits(GPIOB, GPIO_Pin_13);
GPIO_Write(GPIOB, (cmd & 0xF0) | GPIO_ReadOutputData(GPIOB));
GPIO_SetBits(GPIOB, GPIO_Pin14);
delay_us(50);
GPIO_ResetBits(GPIOB, GPIO_Pin_14);
GPIO_SetBits(GPIOB, GPIO_Pin_15);
delay_us(50);
GPIO_ResetBits(GPIOB, GPIO_Pin_15);
}
void lcd_send_data(uint8_t data)
{
GPIO_SetBits(GPIOB, GPIO_Pin_12);
GPIO_ResetBits(GPIOB, GPIO_Pin_13);
GPIO_Write(GPIOB, (data & 0xF0) | GPIO_ReadOutputData(GPIOB));
GPIO_SetBits(GPIOB, GPIO_Pin_14);
delay_us(50);
GPIO_ResetBits(GPIOB, GPIO_Pin_14);
GPIO_Write(GPIOB, ((data & 0x0F) << 4) | GPIO_ReadOutputData(GPIOB));
GPIO_SetBits(GPIOB, GPIO_Pin_15);
delay_us(50);
GPIO_ResetBits(GPIOB, GPIO_Pin_15);
}
void lcd_clear(void)
{
lcd_send_cmd(0x01);
delay_ms(2);
}
void lcd_print(char *str)
{
while (*str)
lcd_send_data(*str++);
}
void lcd_set_cursor(uint8_t row, uint8_t col)
{
if (row == 0)
lcd_send_cmd(0x80 | col);
else
lcd_send_cmd(0xC0 | col);
}
void delay_us(uint32_t us)
{
uint32_t count = us * (SystemCoreClock / 1000000) / 5;
while (count--)
;
}
void delay_ms(uint32_t ms)
{
while (ms--)
delay_us(1000);
}
int main(void)
{
SystemInit();
init_adc();
init_lcd();
char buf[20];
while (1)
{
int temp = read_adc(TEMP_SENSOR_ADC, TEMP_SENSOR_CHANNEL);
float temperature = (3.3 * temp * 100) / 4095.0;
snprintf(buf, 20, "Temperature: %.2f C", temperature);
lcd_clear();
lcd_set_cursor(0, 0);
lcd_print(buf);
int water_level = read_adc(WATER_LEVEL_ADC, WATER_LEVEL_CHANNEL);
snprintf(buf, 20, "Water level: %d %%", (water_level * 100) / 4095);
lcd_set_cursor(1, 0);
lcd_print(buf);
delay_ms(1000);
}
return 0;
} |
|