根据以下程序,分别概括成几个模块的软件设计:#include "stm32f10x.h"
#include "1602.h"
#include "math.h"
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
//以下为汇编函数
void WFI_SET(void); //执行WFI指令
void INTX_DISABLE(void);//关闭所有中断
void INTX_ENABLE(void); //开启所有中断
void MSR_MSP(u32 addr); //设置堆栈地址
#define EnableINT() INTX_ENABLE()
#define DisableINT() INTX_DISABLE()
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
void delay_init()
{
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
u32 reload;
#endif
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
reload=SystemCoreClock/8000000; //每秒钟的计数次数 单位为M
reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间
//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
#else
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
#endif
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
void USART1_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
//USART1
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_PE, ENABLE);
USART_ITConfig(USART1, USART_IT_ERR, ENABLE);
USART1->DR = (0X55 & (uint16_t)0x01FF);
while((USART1->SR&0X40)==0);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void UsartSendData1(unsigned char *send_buff,unsigned long int length)
{
unsigned long int i = 0;
delay_ms(1);
for(i = 0;i < length;i ++)
{
USART1->DR = (send_buff[i] & (uint16_t)0x01FF);
while((USART1->SR&0X40)==0);
}
delay_ms(1);
}
int GQ=0;//保存光强
int LX=0;//光类型 0白光 1黄光 2混合光
int DW=0;//档位 0~5档
int LPWM=0;//亮度 0~100
int moshi=0;//0手动 1自动 2声控
#define LED_B PBout(8)
#define LED_H PBout(7)
#define C_YR PBin(6)
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //ENABLEPBCLK
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //Disable jtag
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//LCD1602 管脚 D0~D7 双向I/O
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//LCD1602 管脚 控制 推挽模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//按键
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//LED灯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/* ADC配置 */
void ADC_Set(unsigned char ch)
{
ADC_InitTypeDef ADC_InitStructure;//ADC结构体变量//注意在一个语句快内变量的声明要放在可执行语句的前面,否则出错,因此要放在ADC1_GPIO_Config();前面
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //使能扫描
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在连续模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制转换,不使用外部触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//转换通道为1
ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
if(ch == ADC_Channel_7)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_239Cycles5);
}
if(ch == ADC_Channel_6)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_239Cycles5);
}
ADC_Cmd(ADC1, ENABLE);//使能ADC1
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
#define ADC_TIMES 10
#define ADCLOST 2
unsigned int GetADC(unsigned char ch)
{
unsigned int i, j;
unsigned int buf[ADC_TIMES];
unsigned long int sum;
long int temp;
static long int XQ = 0;
ADC_Set(ch);
for(i=0; i < ADC_TIMES; i++)
{
buf[i] = ADC_GetConversionValue(ADC1);;
delay_ms(10);
}
for(i = 0; i < ADC_TIMES - 1; i++)
{
for(j = i + 1; j < ADC_TIMES; j++)
{
if(buf[i] > buf[j])
{
temp = buf[i];
}
}
}
sum = 0;
for(i = ADCLOST; i < ADC_TIMES - ADCLOST; i++)
{
sum += buf[i];
}
temp = sum / (ADC_TIMES - 2 * ADCLOST);
if( (XQ>=temp && (XQ-temp)<=1 ) || (XQ<temp && (temp-XQ)<=1))
{
temp = XQ;
}
else
{
XQ = temp;
}
return (unsigned int)(temp>>4);
}
void Display_1(int T1,int T2,int T3,int T4,int T5)
{
char xx=0,yy=0;
//光强
WrByte1602(yy,xx++,'G'); //.
WrByte1602(yy,xx++,'Q');
WrByte1602(yy,xx++,'=');
WrByte1602(yy,xx++,T1%1000/100+'0');
WrByte1602(yy,xx++,T1%100/10+'0');
WrByte1602(yy,xx++,T1%10+'0');
WrByte1602(yy,xx++,' ');
//光类型
WrByte1602(yy,xx++,'T'); //.
WrByte1602(yy,xx++,'Y');
WrByte1602(yy,xx++,'P');
WrByte1602(yy,xx++,'E');
WrByte1602(yy,xx++,'-');
if(T2==0)//0混合 1白光 2黄光
{
WrByte1602(yy,xx++,'B');
WrByte1602(yy,xx++,'H');
}
else if(T2==1)//0混合 1白光 2黄光
{
WrByte1602(yy,xx++,'B');
WrByte1602(yy,xx++,' ');
}
else if(T2==2)//0混合 1白光 2黄光
{
WrByte1602(yy,xx++,'H');
WrByte1602(yy,xx++,' ');
}
WrByte1602(yy,xx++,' ');
xx=0,yy=1;
//档位
WrByte1602(yy,xx++,'D'); //.
WrByte1602(yy,xx++,'W');
WrByte1602(yy,xx++,'=');
WrByte1602(yy,xx++,T3%10+'0');
WrByte1602(yy,xx++,' ');
//亮度
WrByte1602(yy,xx++,'L'); //.
WrByte1602(yy,xx++,'D');
WrByte1602(yy,xx++,'=');
WrByte1602(yy,xx++,T4%1000/100+'0');
WrByte1602
if(T5==0)//0手动 1自动 2声控
{
WrByte1602(yy,xx++,'S');
WrByte1602(yy,xx++,'D');
}
else if(T5==1)//0手动 1自动 2声控
{
WrByte1602(yy,xx++,'Z');
WrByte1602(yy,xx++,'D');
}
else if(T5==2)//0手动 1自动 2声控
{
WrByte1602(yy,xx++,'S');
WrByte1602(yy,xx++,'K');
}
WrByte1602(yy,xx++,' ');
}
//int GQ=0;//保存光强
//int LX=0;//光类型 0白光 1黄光 2混合光
//int DW=0;//档位 0~5档
//int LPWM=0;//亮度 0~100
//int moshi=0;//0手动 1自动 2声控
void anjiansaom(void)
{
static uchar K1,K2,K3;
static uchar K1Flag=0,K2Flag=0,K3Flag=0;
K1 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_9);
K2 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_11);
K3 = GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_10);
//手动/自动
if(K1==0)
{
K1Flag = 1;
}
else
{
if(K1Flag)
{
K1Flag = 0;
if(moshi==1||moshi==2)//0手动 1自动 2声控
{
moshi=0;
}
else
{
moshi=1;
}
}
}
//亮度
if(K2==0)
{
K2Flag = 1;
}
else
{
if(K2Flag)
{
K2Flag = 0;
if(moshi==0)//0手动 1自动 2声控
{
DW++;
if(DW>5)
{
DW=0;
}
LPWM=DW*20;
}
}
}
{
if(K3Flag)
{
K3Flag = 0;
//光类型 0白光 1黄光 2混合光
LX++;
if(LX>2)
{
LX=0;
}
}
}
}
void TimerConfig(TIM_TypeDef* TIMx,unsigned long int time)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2,ENABLE);
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3,ENABLE);
TIM_DeInit(TIMx);
TIM_TimeBaseStructure.TIM_Period = time * 2; /* 自动重装载寄存器周期的值(计数值) */
/* 累计 TIM_Period个频率后产生一个更新或者中断 */
TIM_TimeBaseStructure.TIM_Prescaler= (1000- 1); /* 时钟预分频数 例如:时钟频率=72MHZ/(时钟预分频+1) */
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /* 采样分频 */
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIMx, TIM_FLAG_Update); /* 清除溢出中断标志 */
TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStr
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief 关闭或者开启指定定时器
* @param TIMx: where x can be 1 to 17 to select the TIM peripheral
* @param NewState: new state of the TIMx peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void TimerSW( TIM_TypeDef* TIMx, FunctionalState NewState )
{
TIM_SetCounter(TIMx,0);
TIM_Cmd(TIMx,NewState);
}
int main(void)
{
float temp;
SystemInit();
SystemCoreClockUpdate();
delay_init();
//引脚配置
GPIO_Configuration();
//关闭LED灯
LED_B=0;
LED_H=0;
delay_ms(1000);
//初始化LCD1602
Init1602();
TimerConfig(TIM2,1);
TimerSW(TIM2, ENABLE);
//串口初始化
USART1_init();
while (1)
{
delay_ms(20);
//读取ADC的值,然后计算光强
ADC_Set(0);
//光强
//先读取ADC值
GQ =(255-GetADC(0))/2-60;
if(GQ<0)
{
GQ=0;
}
GQ = GQ*2;
if(GQ>100)
{
GQ = 100;
}
//按键扫描
anjiansaom();
//光强 光类型 档位 亮度 模式
Display_1(GQ,LX,DW,LPWM,moshi);
//自动模式光强控制
//首先得有人才会亮
if(moshi==1)
{
if(C_YR==1 )//传感器输出高电平代表有人
{
//根据亮度计算光亮
//越暗 越亮
LPWM=100-GQ;
}
else
{
LPWM=0;//关灯
}
}
}
}
/**
* @brief 定时器2中断服务函数
* @param TIMx: where x can be 1 to 17 to select the TIM peripheral
* @param NewState: new state of the TIMx peripheral.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void TIM2_IRQHandler(void)
{
static int i=0;
if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )
{
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
// PCout(13)=~PCout(13);
//这里实现PWM 波形的产生
i++;
if(i<=LPWM)
{
//开灯
//暖光 还是白光 还是混合
if(LX==0)//0混合 1白光 2黄光
{
}
}
else
{
//关灯
LED_B=0;LED_H=0;
}
//不能超过100
if(i>100)
{
i=0;
}
}
}
//串口1接收中断
void USART1_IRQHandler(void)
{
char shuju=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
//保存收到的数据
shuju=USART_ReceiveData(USART1); //读取接收到的数据
//收到数据1 //你好小灯 唤醒
if(shuju==1)//进入声控模式
{
moshi=2;
}
if(moshi==2)
{
//收到数据2 //开灯
if(shuju==2)//开灯
{
if(LPWM==0)
{
DW=3;
LPWM=DW*20;
}
}
else if(shuju==3)//关灯
{
DW=0;
LPWM=DW*20;
}
else if(shuju==4)//亮一点
{
DW++;
if(DW>5)
}
}
}
if(USART_GetITStatus(USART1, USART_IT_PE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_PE);
}
if (USART_GetFlagStatus(USART1, USART_IT_LBD) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_LBD);
}
if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{
USART_ReceiveData(USART1);
USART_ClearFlag(USART1, USART_FLAG_ORE);
}
if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_NE);
}
if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_FE);
}
if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_PE);
}
if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_TC);
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{}
}
#endif
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
#include "stm32f10x.h"
#include "1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar ASCII[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//2
/*
PA8~PA15为数据口
*/
#define LCD1602_RS_0 GPIO_ResetBits(GPIOB , GPIO_Pin_12)
#define LCD1602_RS_1 GPIO_SetBits(GPIOB , GPIO_Pin_12)
#define LCD1602_RW_0 GPIO_ResetBits(GPIOB , GPIO_Pin_13)
#define LCD1602_RW_1 GPIO_SetBits(GPIOB , GPIO_Pin_13)
#define LCD1602_EN_0 GPIO_ResetBits(GPIOB , GPIO_Pin_14)
#define LCD1602_EN_1 GPIO_SetBits(GPIOB , GPIO_Pin_14)
#define LCD1602_D0_0 GPIO_ResetBits(GPIOB , GPIO_Pin_15)
#define LCD1602_D0_1 GPIO_SetBits(GPIOB , GPIO_Pin_15)
#define LCD1602_D1_0 GPIO_ResetBits(GPIOA , GPIO_Pin_8)
#define LCD1602_D1_1 GPIO_SetBits(GPIOA , GPIO_Pin_8)
#define LCD1602_D2_0 GPIO_ResetBits(GPIOA , GPIO_Pin_11)
#define LCD1602_D2_1 GPIO_SetBits(GPIOA , GPIO_Pin_11)
#define LCD1602_D3_0 GPIO_ResetBits(GPIOA , GPIO_Pin_12)
#define LCD1602_D3_1 GPIO_SetBits(GPIOA , GPIO_Pin_12)
#define LCD1602_D4_0 GPIO_ResetBits(GPIOA , GPIO_Pin_15)
#define LCD1602_D4_1 GPIO_SetBits(G
#define LCD1602_D6_0 GPIO_ResetBits(GPIOB , GPIO_Pin_4)
#define LCD1602_D6_1 GPIO_SetBits(GPIOB , GPIO_Pin_4)
#define LCD1602_D7_0 GPIO_ResetBits(GPIOB , GPIO_Pin_5)
#define LCD1602_D7_1 GPIO_SetBits(GPIOB , GPIO_Pin_5)
#define GET_LCD1602_D0 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_15)
#define GET_LCD1602_D1 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_8)
#define GET_LCD1602_D2 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_11)
#define GET_LCD1602_D3 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_12)
#define GET_LCD1602_D4 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_15)
#define GET_LCD1602_
void SetLCD1602DValue(unsigned char value)
{
if(value&0x01)
{
LCD1602_D0_1;
}
else
{
LCD1602_D0_0;
}
if(value&0x02)
{
LCD1602_D1_1;
}
{
LCD1602_D2_1;
}
else
{
LCD1602_D2_0;
}
if(value&0x08)
{
LCD1602_D3_1;
}
else
{
LCD1602_D3_0;
}
if(value&0x10)
{
LCD1602_D4_1;
}
else
{
LCD1602_D4_0;
}
if(value&0x20)
{
LCD1602_D5_1;
}
else
{
LCD1602_D5_0;
}
if(value&0x40)
if(value&0x80)
{
LCD1602_D7_1;
}
else
{
LCD1602_D7_0;
}
}
unsigned char GetLCD1602DValue(void)
{
unsigned char dat;
dat = 0x00;
if(GET_LCD1602_D0)
{
dat = dat |0x01;
}
if(GET_LCD1602_D1)
{
dat = dat |0x02;
}
if(GET_LCD1602_D2)
{
dat = dat |0x04;
}
if(GET_LCD1602_D3)
{
dat = dat |0x08;
}
if(GET_LCD1602_D4)
{
dat = dat |0x10;
}
if(GET_LCD1602_D5)
{
dat = dat |0x20;
}
if(GET_LCD1602_D6)
{
dat = dat |0x40;
}
if(GET_LCD1602_D7)
{
dat = dat |0x80;
}
return(dat);
}
/*******************通用延时子程序**************************/
void mDelay(uint i)
{
for (;i>0;i--)
{uchar j=10;while(--j);}
}
void LCD1602DTest(void)
{
LCD1602_RS_1;
LCD1602_RW_1;
LCD1602_EN_1;
SetLCD1602DValue(0x00);
mDelay(100);
mDelay(100);
LCD1602_EN_0;
SetLCD1602DValue(0xFF);
mDelay(100);
mDelay(100);
LCD1602_RS_0;
LCD1602_RW_0;
LCD1602_EN_0;
SetLCD1602DValue(0x00);
}
/*************************************************************
函数名称:读忙状态子函数
全局变量:无
参数说明:无
返回说明:无
版 本:1.0
说 明:读取LCD1602忙状态
**************************************************************/
void Read1602() //读忙状态
{
long int i=90000; //建一个循环变量避免器件发生故障停在这里
SetLCD1602DValue(0xff);
LCD1602_RS_0;
LCD1602_RW_1; //设置LCD为读取数据状态
LCD1602_EN_1; //使能LCD,高电平
while ((i--)&&(GetLCD1602DValue()&0x80)); //检测数据口最高位状态,为0则空闲
LCD1602_EN_0; //关闭使能
}
/**************************************************************
函数名称:写操作子函数
全局变量:无
参数说明:Dat为数据,command为指令(1为写数据,0为写指令)
返回说明:无
版 本:1.0
说 明:往LCD1602写入数据、指令
***************************************************************/
void Write1602(uchar Dat,unsigned char command)
{
Read1602();
SetLCD1602DValue(Dat);
if(command)
{
LCD1602_RS_1; //RS为1写数据、为0写指令
}
else
{
LCD1602_RS_0;
}
LCD1602_RW_0; //RW为低,进行写操作
LCD1602_EN_1;
LCD1602_EN_0; //E端控制一个高脉冲
}
/***************************************************************
函数名称:LCD1602初始化子函数
全局变量:无
参数说明:无
返回说明:无
版 本:1.0
说 明:设置工作模式、清屏、开显示
***************************************************************/
void Init1602(void)
{
LCD1602DTest();
mDelay(10);
mDelay(10);
Write1602(0x38,0); //8位点阵方式
mDelay(10);
Write1602(0x38,0);
mDelay(10);
Write1602(0x38,0);
mDelay(10);
Write1602(0x38,0);
mDelay(10);
Write1602(0x01,0); //清屏
mDelay(10);
Write1602(0x0c,0); //开显示,光标不显示
}
void WrByte1602_EX(uchar x,uchar y,uchar dat)
{
Write1602(0x80+(x<<6)+y,0); //合并生成地址
Write1602(dat,1); //写入数据
}
void WrByte1602(uchar x,uchar y,uchar dat)
{
Write1602(0x80+(x<<6)+y,0); //合并生成地址
Write1602(dat,1); //写入数据
}
/***************************************************************
函数名称:LCD1602整行字符串写入子函数
全局变量:无
参数说明:x为写入的行(0或1),*p为写入的字符串数组
返回说明:无
版 本:1.0
说 明:在LCD1602任意行写入字符串
****************************************************************/
void LCD_Write_String(uchar x1,uchar x,uchar *p)
{
x1 = 1;
Write1602(0x80+(x<<6),0); //合并生成行首地址
while(*p) {Write1602(*p,1);p++;} //逐个字符写入
}
#include "stm32f10x.h"
#include "1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar ASCII[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//2
/*
PA8~PA15为数据口
*/
#define LCD1602_RS_0 GPIO_ResetBits(GPIOB , GPIO_Pin_12)
#define LCD1602_RS_1 GPIO_SetBits(GPIOB , GPIO_Pin_12)
#define LCD1602_RW_0 GPIO_ResetBits(GPIOB , GPIO_Pin_13)
#define LCD1602_RW_1 GPIO_SetBits(GPIOB , GPIO_Pin_13)
#define LCD1602_EN_0 GPIO_ResetBits(GPIOB , GPIO_Pin_14)
#define LCD1602_EN_1 GPIO_SetBits(GPIOB , GPIO_Pin_14)
#define LCD1602_D0_0 GPIO_ResetBits(GPIOB , GPIO_Pin_15)
#define LCD1602_D0_1 GPIO_SetBits(GPIOB , GPIO_Pin_15)
#define LCD1602_D1_0 GPIO_ResetBits(GPIOA , GPIO_Pin_8)
#define LCD1602_D1_1 GPIO_SetBits(GPIOA , GPIO_Pin_8)
#define LCD1602_D2_0 GPIO_ResetBits(GPIOA , GPIO_Pin_11)
#define LCD1602_D2_1 GPIO_SetBits(GPIOA , GPIO_Pin_11)
#define LCD1602_D3_0 GPIO_ResetBits(GPIOA , GPIO_Pin_12)
#define LCD1602_D3_1 GPIO_SetBits(GPIOA , GPIO_Pin_12)
#define LCD1602_D4_0 GPIO_ResetBits(GPIOA , GPIO_Pin_15)
#define LCD1602_D4_1 GPIO_SetBits(GPIOA , GPIO_Pin_15)
#define LCD1602_D5_0 GPIO_ResetBits(GPIOB , GPIO_Pin_3)
#define LCD1602_D5_1 GPIO_SetBits(GPIOB , GPIO_Pin_3)
#define LCD1602_D6_0 GPIO_ResetBits(GPIOB , GPIO_Pin_4)
#define LCD1602_D6_1 GPIO_SetBits(GPIOB , GPIO_Pin_4)
#define LCD1602_D7_0 GPIO_ResetBits(GPIOB , GPIO_Pin_5)
#define LCD1602_D7_1 GPIO_SetBits(GPIOB , GPIO_Pin_5)
#define GET_LCD1602_D0 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_15)
#define GET_LCD1602_D1 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_8)
#define GET_LCD1602_D2 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_11)
#define GET_LCD1602_D3 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_12)
#define GET_LCD1602_D4 GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_15)
#define GET_LCD1602_D5 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_3)
#define GET_LCD1602_D6 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_4)
#define GET_LCD1602_D7 GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_5)
void SetLCD1602DValue(unsigned char value)
{
if(value&0x01)
{
LCD1602_D0_1;
}
else
{
LCD1602_D0_0;
}
if(value&0x02)
{
LCD1602_D1_1;
}
else
{
LCD1602_D1_0;
}
if(value&0x04)
{
LCD1602_D2_1;
}
else
{
LCD1602_D2_0;
}
if(value&0x08)
{
LCD1602_D3_1;
}
else
{
LCD1602_D3_0;
}
if(value&0x10)
{
LCD1602_D4_1;
}
else
{
LCD1602_D4_0;
}
if(value&0x20)
{
LCD1602_D5_1;
}
else
{
LCD1602_D5_0;
}
if(value&0x40)
{
LCD1602_D6_1;
}
else
{
LCD1602_D6_0;
}
if(value&0x80)
{
LCD1602_D7_1;
}
else
{
LCD1602_D7_0;
}
}
unsigned char GetLCD1602DValue(void)
{
unsigned char dat;
dat = 0x00;
if(GET_LCD1602_D0)
{
dat = dat |0x01;
}
if(GET_LCD1602_D1)
{
dat = dat |0x02;
}
if(GET_LCD1602_D2)
{
dat = dat |0x04;
}
if(GET_LCD1602_D3)
{
dat = dat |0x08;
}
if(GET_LCD1602_D4)
{
dat = dat |0x10;
}
if(GET_LCD1602_D5)
{
dat = dat |0x20;
}
if(GET_LCD1602_D6)
{
dat = dat |0x40;
}
if(GET_LCD1602_D7)
{
dat = dat |0x80;
}
return(dat);
}
/*******************通用延时子程序**************************/
void mDelay(uint i)
{
for (;i>0;i--)
{uchar j=10;while(--j);}
}
void LCD1602DTest(void)
{
LCD1602_RS_1;
LCD1602_RW_1;
LCD1602_EN_1;
SetLCD1602DValue(0x00);
mDelay(100);
mDelay(100);
LCD1602_RS_0;
LCD1602_RW_0;
LCD1602_EN_0;
SetLCD1602DValue(0xFF);
mDelay(100);
mDelay(100);
LCD1602_RS_0;
LCD1602_RW_0;
LCD1602_EN_0;
SetLCD1602DValue(0x00);
}
/*************************************************************
函数名称:读忙状态子函数
全局变量:无
参数说明:无
返回说明:无
版 本:1.0
说 明:读取LCD1602忙状态
**************************************************************/
void Read1602() //读忙状态
{
long int i=90000; //建一个循环变量避免器件发生故障停在这里
SetLCD1602DValue(0xff);
LCD1602_RS_0;
LCD1602_RW_1; //设置LCD为读取数据状态
LCD1602_EN_1; //使能LCD,高电平
while ((i--)&&(GetLCD1602DValue()&0x80)); //检测数据口最高位状态,为0则空闲
LCD1602_EN_0; //关闭使能
}
/**************************************************************
函数名称:写操作子函数
全局变量:无
参数说明:Dat为数据,command为指令(1为写数据,0为写指令)
返回说明:无
版 本:1.0
说 明:往LCD1602写入数据、指令
***************************************************************/
void Write1602(uchar Dat,unsigned char command)
{
Read1602();
SetLCD1602DValue(Dat);
if(command)
{
LCD1602_RS_1; //RS为1写数据、为0写指令
}
else
{
LCD1602_RS_0;
}
LCD1602_RW_0; //RW为低,进行写操作
LCD1602_EN_1;
LCD1602_EN_0; //E端控制一个高脉冲
}
/***************************************************************
函数名称:LCD1602初始化子函数
全局变量:无
参数说明:无
返回说明:无
版 本:1.0
说 明:设置工作模式、清屏、开显示
***************************************************************/
void Init1602(void)
{
LCD1602DTest();
mDelay(10);
mDelay(10);
Write1602(0x38,0); //8位点阵方式
mDelay(10);
Write1602(0x38,0);
mDelay(10);
mDelay(10);
Write1602(0x01,0); //清屏
mDelay(10);
Write1602(0x0c,0); //开显示,光标不显示
}
void WrByte1602_EX(uchar x,uchar y,uchar dat)
{
Write1602(0x80+(x<<6)+y,0); //合并生成地址
Write1602(dat,1); //写入数据
}
void WrByte1602(uchar x,uchar y,uchar dat)
{
Write1602(0x80+(x<<6)+y,0); //合并生成地址
Write1602(dat,1); //写入数据
}
/***************************************************************
函数名称:LCD1602整行字符串写入子函数
全局变量:无
参数说明:x为写入的行(0或1),*p为写入的字符串数组
返回说明:无
版 本:1.0
说 明:在LCD1602任意行写入字符串
****************************************************************/
void LCD_Write_String(uchar x1,uchar x,uchar *p)
{
x1 = 1;
Write1602(0x80+(x<<6),0); //合并生成行首地址
while(*p) {Write1602(*p,1);p++;} //逐个字符写入
}