这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 有奖活动 » STM32C0116DK开发探索记(1)

共1条 1/1 1 跳转至

STM32C0116DK开发探索记(1)

菜鸟
2026-06-11 11:37:37     打赏

为了制作一个小巧低功耗的温湿度计,特选取了一款迷你型的开发板STM32C0116_DK其外观见图1和图2所示,由此可知它是采用双面器件布局,只是背面的器件比较少。

image.png

1 正面布局

image.png

2 背面布局 

在完成程序下载的情况下,单是一个20PIN的直插式管座就可容下其核心板的体量。再配上蓝牙透传模块及温湿度传感器,其尺寸也大不到哪去。

本以为只用一个GPIO引脚外加2个串口引脚就可以解决问题,然而理想很丰满,现实很骨感,当找到相关例程才发现,竟连个串口的例程都没通过,见图3所示。

image.png

3 例程内容 

无奈之下,只好自行探索来解决啦,并尽可能将其潜在的性能发掘出来。 

既然可利用的资源不多,就索性从GPIO入手,逐步趟出一些门道来。

1. 彩灯效果的实现

在例程中提供了板载LED的示例程序,参照它的使用方法,不难掌握其引脚的配置方法及输出电平的控制。

由于该开发板在引脚的使用上没有采用连续排列的方式,而是若干个引脚分为一组来排列,因此较耗费排针。

image.png

4 引脚排列关系 

为此,是使用3个相对接近的引脚来连接RGB_LED模块,具体的连接关系为:

R----PC15

G----PA7

B----PB7

image.png

5 器件连接 

相应的引脚配置函数为:

void RGB_config(void)
{
  __HAL_RCC_GPIOB_CLK_ENABLE();
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 
  __HAL_RCC_GPIOA_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
  __HAL_RCC_GPIOC_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}


实现彩灯控制效果的主程序为:

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    LED3_GPIO_CLK_ENABLE();
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pin = LED3_PIN;
    HAL_GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStruct);
    RGB_config();
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
    while (1)
    {
         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);   //R
         HAL_Delay(500);
         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
         HAL_Delay(500);
         HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_7);   //G
         HAL_Delay(500);
         HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_7);
         HAL_Delay(500);
         HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);   //B
         HAL_Delay(500);
         HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
         HAL_Delay(500);    
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);    //Y
         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
         HAL_Delay(500);  
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
         HAL_Delay(500);   
         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);   //P
         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
         HAL_Delay(500);  
         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
         HAL_Delay(500);   
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);    //BL
         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
         HAL_Delay(500);  
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
         HAL_Delay(500);   
    }
}


经程序的编译下载,其测试效果见图6至图11所示,说明GPIO的使用成功。

image.png

6 点亮红灯

image.png

7 点亮绿灯

image.png

8 点亮蓝灯

image.png

9 粉色效果

image.png

10 黄色效果

image.png

11 浅蓝色效果 

比较有意思的是,开发板既支持传统的调试器下载方式,也支持将目标文件拖如开发板虚拟U盘的方式。

image.png

12 调试器连接状态

image.png

13 虚拟U

2.OLED屏现实驱动

有了GPIO的使用经验,就不难以模拟的方式来驱动I2C接口的OLED屏,以便于显示信息。

OLED屏与开发板的连接关系为:

SCK----PA7

SDA----PC15 

模拟I2C方式方式字节数据的函数为: 

void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)  
{
m=da;
m=m&0x80;
if(m==0x80)
{
  OLED_SDIN_Set();
}
else OLED_SDIN_Clr();
delay_us(3);
da=da<<1;
OLED_SCLK_Set();
delay_us(3);
OLED_SCLK_Clr();
delay_us(3);
}
}

OLED屏的初始化函数为;

void OLED_Init(void)
{
    Write_IIC_Command(0xAE); 
    Write_IIC_Command(0x20); 
    Write_IIC_Command(0x10);
    Write_IIC_Command(0xb0);
    Write_IIC_Command(0xc8);
    Write_IIC_Command(0x00);
    Write_IIC_Command(0x10);
    Write_IIC_Command(0x40);
    Write_IIC_Command(0x81);
    Write_IIC_Command(0xdf);
    Write_IIC_Command(0xa1);
    Write_IIC_Command(0xa6);
    Write_IIC_Command(0xa8);
    Write_IIC_Command(0x3F);
    Write_IIC_Command(0xa4);
    Write_IIC_Command(0xd3);
    Write_IIC_Command(0x00);
    Write_IIC_Command(0xd5);
    Write_IIC_Command(0xf0);
    Write_IIC_Command(0xd9);
    Write_IIC_Command(0x22); 
    Write_IIC_Command(0xda);
    Write_IIC_Command(0x12);
    Write_IIC_Command(0xdb);
    Write_IIC_Command(0x20);
    Write_IIC_Command(0x8d);
    Write_IIC_Command(0x14);
    Write_IIC_Command(0xaf);l
}

OLED屏的清屏函数为:

void OLED_Clear(void)  
{  
uint8_t i,n;      
for(i=0;i<8;i++)  
{  
OLED_WR_Byte (0xb0+i,OLED_CMD);    
OLED_WR_Byte (0x00,OLED_CMD);      
OLED_WR_Byte (0x10,OLED_CMD);       
for(n=0;n<128;n++)OLED_WR_Byte(0x0,OLED_DATA); 
} 
}

显示字符的函数为:

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{       
unsigned char c=0,i=0; 
c=chr-' ';
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y); 
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
else
{ 
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);

}
}

显示数值的函数为:

void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{          
uint8_t t,temp;
uint8_t enshow=0;         
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}else enshow=1; 
   
}
  OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
}
}

显示字符串的函数为:

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120) {x=0;y+=2;}
j++;
}
}

测试OLED屏显示效果的主程序为:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  OLED_config(); 
  OLED_Init();
  OLED_Clear();
  OLED_ShowString(0,2," STM32C0116_DK",16);
  while (1);
}

经测试,其显示效果见图14所示,说明驱动成功。后面的测试,就可以凭他来观察信息结果啦。

image.png

14 显示效果

3.RTC电子时钟的实现

有了OLED屏的显示功能,就可验证RTC的计时功能,并实现电子时钟功能。

RTC的初始化函数为:

static void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  hrtc.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u)
  {
  sTime.Hours = 0x2;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.SubSeconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_DECEMBER;
  sDate.Date = 0x6;
  sDate.Year = 0x21;
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  }
}

显示RTC计时值的函数为:

static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
{
  RTC_DateTypeDef sdatestructureget;
  RTC_TimeTypeDef stimestructureget;
  HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
  sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  OLED_ShowString(8,4,showtime,16);
}

实现电子时钟功能的测试主程序为:

int main(void)
{
  HAL_Init();
  BSP_LED_Init(LED3);
  MX_GPIO_Init();
  SystemClock_Config();
  OLED_config();
  OLED_Init();
  OLED_Clear();
  OLED_ShowString(0,1," STM32C0116_DK",16);
  MX_RTC_Init();
  RTCStatus = 1;
  while (1)
  {
        RTC_CalendarShow(aShowTime, aShowDate);
  }
}

经实际测试,其显示效果如图15所示,说明功能正确。

image.png

15 计时效果

至此,就实现了电子时钟功能,后续再解决A/D数据采集和串口通信等问题。




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]