七夕————鹊桥PCB,工程开源,要文件的可以在854217089群里找我哦,白丁客。 七夕,这个美丽的日子里。我也想画一块板子-----藉此,有情人终成眷属。先把效果图晒一下吧哈哈哈 介绍一下这块板子,以免各位看官看得云里雾里: 这是利用Altium Designer 画图软件做的一个基于STM32F103C8T6单片机的系统板,搭载的若干个LED灯,最大的特点是将“七夕”的元素用在丝印层画图的方式表现出来,这是一对“有情人”,板子启动后,LED组成的“鹊桥”交替闪烁。当然了,Altium Designer、STM32的原始工程文件需要的跟我沟通,最重要的也就体现在这里,我在系统板中引出了串口,直接接口Micro USB就可以进行调试了。有初学的小伙伴可以对此进行二次开发哦
硬件设计: 1、电路使用STM32f103C8T6,片内FLASH:64KB, RAM:20K,48脚 2、控制电路:LED采用74LS138译码器输出控制信号,通过三极管驱动,这样能够实现以较少的管脚控制较多的外围设备。 3、DEBUG电路:将JTAG、SW调试引脚尽数引出。将串口通过CH340C转换电平后引出。 4、复位电路:采用RC复位,考虑到没有外围干扰和噪声,省去了电压监控。 软件设计: 1、首先,初始化系统时钟,调用标准固件库V3.5. RCC_Configuration();//展开这个函数,可以得到如下代码 void RCC_Configuration(void) { SystemInit(); RCC_HSICmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)==RESET); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); /* 设置高速AHB时钟(PCLK2)RCC_HCLK_Div1——APB2时钟 = HCLK*/ RCC_PCLK1Config(RCC_HCLK_Div2); /*设置低速AHB时钟(PCLK1)RCC_HCLK_Div2——APB1时钟 = HCLK / 2*/ FLASH_SetLatency(FLASH_Latency_2); /*设置FLASH存储器延时时钟周期数FLASH_Latency_2 2延时周期*/ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /*选择FLASH预取指缓存的模,预取指缓存使能*/ RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);/*设置PLL时钟源及倍频系数,频率为8/2*16=64Mhz*/ RCC_PLLCmd(ENABLE); /*使能PLL */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ; /*检查指定的RCC标志位(PLL准备好标志)设置与否*/ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /*设置系统时钟(SYSCLK) */ while(RCC_GetSYSCLKSource() != 0x08); /*0x08:PLL作为系统时钟 */ } 时钟配置,使用HSI作为时钟源,经过二倍分频后送入PLL,再通过PLL倍频到64MHz. 2、虽然板子不需要串口输出数据,但是为了方便调试和二次开发,所以将串口电路引出,直接插Micro USB即可在串口调试助手中看到打印的信息,串口初始化代码如下: void USART1_Configuration(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA,ENABLE);
USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate=115200; 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_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
//USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); USART_Cmd(USART1,ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC);
GPIO_InitTypeDefGPIO_InitStructure; GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); } 3、因为这个板子只用到了串口和基本IO,所以没有配置NVIC,但是将配置方法列出,例子中,将DMA和定时器的中断优先级进行了配置,需要注意的是,中断优先级分组在整个程序中只配置一次就可以: void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 因为用灯带的原因,运行花样灯的时候需要延时,所以,延时程序由以下代码产生(注意:系统时钟为64M): void delay_ms(u16 nms) { u32 temp; SysTick->LOAD = 8000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } 4、在stm32中使用printf()的方法: (1)工程使用的是MDK,属性的“Target“-》”Code Generation“中勾选”Use MicroLIB (2)main 文件中 包含“stdio.h”(标准输入输出头文件) (3)在主函数文件中重定义<fputc>函数 int fputc(int ch, FILE *f) { USART_SendData(USART1, (unsigned char) ch); // USART1 可以换成 USART2 等 while (!(USART1->SR & USART_FLAG_TXE)); return (ch); } 5、控制信号管脚初始化: void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_6|GPIO_Pin_7); GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_OD; //推挽输出 GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口 } 6、串口的不定长指令接收: 程序里利用了RXNE这个接收中断,当接收到数据时立即产生中断,利用这个标志位,将指定长度或者标志的指令数据接收完毕后再对指令进行处理。处理完毕后要将处理的数组清零,并且长度计数值要清零,为下一次接收指令做准备。 7、完成系统、外设初始化后就可以进入大循环程序了: 由于外设LED的驱动使用了74LS138译码器,所以只需要对A5,A6,A7三个IO口编写循环程序就可以驱动8个LED闪烁,程序的使用方法:向串口写入指令控制循环的速度即可。指令如下: M1(CR,LF) M2(CR,LF) M3(CR,LF) 下达指令后只能进入一种循环模式,不能退出,当然你有更好的花样,可以进行二次开发。
|