坑爹的时间安排
十点半下班,看代码的时间都没有了
32楼
串口1串口2实现。参考正点原子的程序
先放这,有时间了再做注释。
串口1
//串口1发送数据 2012.03.21
void UART1_SendByte(u8 data)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) data;
}
#ifdef EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0; //接收状态标记
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x40;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=res;
USART_RX_STA++;
if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
//初始化IO 串口1
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH&=0XFFFFF00F;
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
串口2:
void uart2_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB1ENR|=1<<17; //使能串口2时钟
GPIOA->CRL&=0XFFFF00FF;
GPIOA->CRL|=0X00008B00;//IO状态设置
RCC->APB1RSTR|=1<<17; //复位串口1
RCC->APB1RSTR&=~(1<<17);//停止复位
//波特率设置
USART2->BRR=mantissa; // 波特率设置
USART2->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
//使能接收中断
USART2->CR1|=1<<8; //PE中断使能
USART2->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART2_IRQChannel,2);//组2,最低优先级
#endif
}
void USART2_SendByte(u8 data)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR = (u8) data;
//return ch;
}
#ifdef EN_USART2_RX //如果使能了接收
//串口2中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART2_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART2_RX_STA=0; //接收状态标记
void USART2_IRQHandler(void)
{
u8 res;
if(USART2->SR&(1<<5))//接收到数据
{
res=USART2->DR;
if((USART2_RX_STA&0x80)==0)//接收未完成
{
if(USART2_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
else USART2_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART2_RX_STA|=0x40;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3F]=res;
USART2_RX_STA++;
if(USART2_RX_STA>63)USART2_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
先放这,有时间了再做注释。
串口1
//串口1发送数据 2012.03.21
void UART1_SendByte(u8 data)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) data;
}
#ifdef EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0; //接收状态标记
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x40;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=res;
USART_RX_STA++;
if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
//初始化IO 串口1
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH&=0XFFFFF00F;
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
串口2:
void uart2_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB1ENR|=1<<17; //使能串口2时钟
GPIOA->CRL&=0XFFFF00FF;
GPIOA->CRL|=0X00008B00;//IO状态设置
RCC->APB1RSTR|=1<<17; //复位串口1
RCC->APB1RSTR&=~(1<<17);//停止复位
//波特率设置
USART2->BRR=mantissa; // 波特率设置
USART2->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
//使能接收中断
USART2->CR1|=1<<8; //PE中断使能
USART2->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART2_IRQChannel,2);//组2,最低优先级
#endif
}
void USART2_SendByte(u8 data)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR = (u8) data;
//return ch;
}
#ifdef EN_USART2_RX //如果使能了接收
//串口2中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART2_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART2_RX_STA=0; //接收状态标记
void USART2_IRQHandler(void)
{
u8 res;
if(USART2->SR&(1<<5))//接收到数据
{
res=USART2->DR;
if((USART2_RX_STA&0x80)==0)//接收未完成
{
if(USART2_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
else USART2_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART2_RX_STA|=0x40;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3F]=res;
USART2_RX_STA++;
if(USART2_RX_STA>63)USART2_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
33楼
意淫SDIO,因为没有使用SDIO的 板子。只能意淫了
网上找来个SDIO的代码,竟然是用库函数。
我最讨厌的就是库函数。
准备改写简化,代码放到此处
今晚的成果,SDIO引脚初始化,纯属意淫,没经过测试:
void SD_LowLevel_Init(void)
{
RCC->APB2ENR |= 1<<4; //使能GPIOC时钟
RCC->APB2ENR |= 1<<5; //使能GPIOD时钟
RCC->APB2ENR |= 1<<8; //使能GPIOG时钟
//初始化GPIOc的8、9、10、11、12脚 时钟50M 复用功能 推挽输出
GPIOC->CRH &= 0xFFF00000;
GPIOC->CRH |= 0x000BBBBB;
//初始化GPIOD 的2、3脚 时钟50M 推挽输出
GPIOD->CRL &= 0xFFFF00FF;
GPIOD->CRL |= 0x0000BB00;
//初始化GPIOG 的8引脚 时钟50M 推挽输出
GPIOG->CRH &= 0xFFFFFFF0;
GPIOG->CRH |= 0x0000000B;
//开启SDIO时钟 和 DMA2时钟,通过RCC_AHB
RCC->AHBENR |= 1<<10;
RCC->AHBENR |= 1<1;
}
网上找来个SDIO的代码,竟然是用库函数。
我最讨厌的就是库函数。
准备改写简化,代码放到此处
今晚的成果,SDIO引脚初始化,纯属意淫,没经过测试:
void SD_LowLevel_Init(void)
{
RCC->APB2ENR |= 1<<4; //使能GPIOC时钟
RCC->APB2ENR |= 1<<5; //使能GPIOD时钟
RCC->APB2ENR |= 1<<8; //使能GPIOG时钟
//初始化GPIOc的8、9、10、11、12脚 时钟50M 复用功能 推挽输出
GPIOC->CRH &= 0xFFF00000;
GPIOC->CRH |= 0x000BBBBB;
//初始化GPIOD 的2、3脚 时钟50M 推挽输出
GPIOD->CRL &= 0xFFFF00FF;
GPIOD->CRL |= 0x0000BB00;
//初始化GPIOG 的8引脚 时钟50M 推挽输出
GPIOG->CRH &= 0xFFFFFFF0;
GPIOG->CRH |= 0x0000000B;
//开启SDIO时钟 和 DMA2时钟,通过RCC_AHB
RCC->AHBENR |= 1<<10;
RCC->AHBENR |= 1<1;
}
36楼
还是研究研究库吧
都说库好用。从稀里糊涂看起
建立个工程 在RBT6上先试验下
再看下零件 发现买错了几个
电源插头买大了 SMJB5.0买成了15.0了
我自己手里的排座都是单排的 液晶不好插
VS1003也白买了 那个转接板不能用 VS1003的大小 的片子脚对不上
都说库好用。从稀里糊涂看起
建立个工程 在RBT6上先试验下
再看下零件 发现买错了几个
电源插头买大了 SMJB5.0买成了15.0了
我自己手里的排座都是单排的 液晶不好插
VS1003也白买了 那个转接板不能用 VS1003的大小 的片子脚对不上
38楼
弄了两天 终于搞明白用库弄GPIO点灯了
用库建好模板之后,加入头文件LED.h和LED.c
LED.h内容
#include "stm32f10x_gpio.h"
#define LED_ALL (GPIO_Pin_8)
typedef enum
{
ON = 1,
OFF = 0
}Led_SettingDef;
#define LED1_GPIO_PORT (GPIOA)
#define LED1_GPIO_CLK (RCC_APB2Periph_GPIOA )
#define LED2_GPIO_PORT (GPIOD)
#define LED2_GPIO_CLK (RCC_APB2Periph_GPIOD )
typedef enum
{
LED1 = GPIO_Pin_8,
LED2 = GPIO_Pin_2
}Led_TypeDef;
void LED_Init(Led_TypeDef led);
void LED_Set(Led_TypeDef led,Led_SettingDef set);
void LED_Toggle(Led_TypeDef led);
LED.c内容
#include "led.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_conf.h"
//LED端口和时钟初始化
void LED_Init(Led_TypeDef led)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义 GPIO 操作及配置结构体
/* Enable the GPIO_LED Clock */
// if(led == LED1)
// {
// RCC_APB2PeriphClockCmd(LED1_GPIO_CLK, ENABLE);//使能 LED 端口时钟
// }
// else if (led == LED2)
// {
// RCC_APB2PeriphClockCmd(LED2_GPIO_CLK, ENABLE);//使能 LED 端口时钟
// }
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin =led;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//配置 GPIO 为输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置 GPIO 速度为 50MHz
if(led == LED1 )
{
RCC_APB2PeriphClockCmd(LED1_GPIO_CLK, ENABLE);//使能 LED 端口时钟
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);//初始化 LED 相关的 GPIO
}
else if(led == LED2)
{
RCC_APB2PeriphClockCmd(LED2_GPIO_CLK, ENABLE);//使能 LED 端口时钟
GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);//初始化 LED 相关的 GPIO
}
}
//开关LED
void LED_Set(Led_TypeDef led,Led_SettingDef set)
{
if(led == LED1)
{
if(set==ON)
GPIOA->BRR = led;//点亮相应的 LED,即相应的 GPIO 输出低电平
else
GPIOA->BSRR = led;//熄灭相应的 LED,即相应的 GPIO 输出高电平
}
else if(led == LED2)
{
if(set==ON)
GPIOD->BRR = led;//点亮相应的 LED,即相应的 GPIO 输出低电平
else
GPIOD->BSRR = led;//熄灭相应的 LED,即相应的 GPIO 输出高电平
}
}
//反转LED
void LED_Toggle(Led_TypeDef led)
{
if(led == LED1)
{
GPIOA->ODR ^= led;//交替使 LED 相应的 GPIO 输出高电平或低电平
}
else if(led == LED2)
{
GPIOD->ODR ^=led;
}
}
用库建好模板之后,加入头文件LED.h和LED.c
LED.h内容
#include "stm32f10x_gpio.h"
#define LED_ALL (GPIO_Pin_8)
typedef enum
{
ON = 1,
OFF = 0
}Led_SettingDef;
#define LED1_GPIO_PORT (GPIOA)
#define LED1_GPIO_CLK (RCC_APB2Periph_GPIOA )
#define LED2_GPIO_PORT (GPIOD)
#define LED2_GPIO_CLK (RCC_APB2Periph_GPIOD )
typedef enum
{
LED1 = GPIO_Pin_8,
LED2 = GPIO_Pin_2
}Led_TypeDef;
void LED_Init(Led_TypeDef led);
void LED_Set(Led_TypeDef led,Led_SettingDef set);
void LED_Toggle(Led_TypeDef led);
LED.c内容
#include "led.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_conf.h"
//LED端口和时钟初始化
void LED_Init(Led_TypeDef led)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义 GPIO 操作及配置结构体
/* Enable the GPIO_LED Clock */
// if(led == LED1)
// {
// RCC_APB2PeriphClockCmd(LED1_GPIO_CLK, ENABLE);//使能 LED 端口时钟
// }
// else if (led == LED2)
// {
// RCC_APB2PeriphClockCmd(LED2_GPIO_CLK, ENABLE);//使能 LED 端口时钟
// }
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin =led;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//配置 GPIO 为输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置 GPIO 速度为 50MHz
if(led == LED1 )
{
RCC_APB2PeriphClockCmd(LED1_GPIO_CLK, ENABLE);//使能 LED 端口时钟
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);//初始化 LED 相关的 GPIO
}
else if(led == LED2)
{
RCC_APB2PeriphClockCmd(LED2_GPIO_CLK, ENABLE);//使能 LED 端口时钟
GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);//初始化 LED 相关的 GPIO
}
}
//开关LED
void LED_Set(Led_TypeDef led,Led_SettingDef set)
{
if(led == LED1)
{
if(set==ON)
GPIOA->BRR = led;//点亮相应的 LED,即相应的 GPIO 输出低电平
else
GPIOA->BSRR = led;//熄灭相应的 LED,即相应的 GPIO 输出高电平
}
else if(led == LED2)
{
if(set==ON)
GPIOD->BRR = led;//点亮相应的 LED,即相应的 GPIO 输出低电平
else
GPIOD->BSRR = led;//熄灭相应的 LED,即相应的 GPIO 输出高电平
}
}
//反转LED
void LED_Toggle(Led_TypeDef led)
{
if(led == LED1)
{
GPIOA->ODR ^= led;//交替使 LED 相应的 GPIO 输出高电平或低电平
}
else if(led == LED2)
{
GPIOD->ODR ^=led;
}
}
40楼
一下午和晚上的功劳
开始焊接板子。先焊接电源,USB口部分电源。
1117-3.3v芯片 焊好 插上USB看下,输出是3.3V没错。然后才敢喊MCU。
MCU先在焊盘上挂一层锡,芯片放上。刀型烙铁放在外边焊盘上加温,时间不能太长。锡化开之后,刀头往外拨。有搭锡的引脚时,烙铁头沾上焊锡膏再点一次,基本上就能松开。
我烙铁调到300度左右,锡刚好能化开。
没测试MCU是不是好了,明天测试下再开始焊别的。
我在群里边问了不少焊接的问题,感谢大家给我的帮助。
同事也欢迎大家加入,共同讨论这次DIY活动。群号120856028。
开始焊接板子。先焊接电源,USB口部分电源。
1117-3.3v芯片 焊好 插上USB看下,输出是3.3V没错。然后才敢喊MCU。
MCU先在焊盘上挂一层锡,芯片放上。刀型烙铁放在外边焊盘上加温,时间不能太长。锡化开之后,刀头往外拨。有搭锡的引脚时,烙铁头沾上焊锡膏再点一次,基本上就能松开。
我烙铁调到300度左右,锡刚好能化开。
没测试MCU是不是好了,明天测试下再开始焊别的。
我在群里边问了不少焊接的问题,感谢大家给我的帮助。
同事也欢迎大家加入,共同讨论这次DIY活动。群号120856028。
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |