1.开发环境选择
之前使用KEIL,一直都是5.00版本,使用起来STM32F系列的都妥妥的,都不知道为什么,在L053上面,遇到了各式各样的问题,先开始也没多想,觉得ST公司提供的文件非常非常的正确,可是在重新安装了KEIL5.10,KEIL5.12时,问题还是不停的出现
毫不犹豫,把遇到的其中几个分享一下-----首先是STM32PACK文件的问题,KEIL在安装的时候不知道抽了什么风,老是PACKINSTALLER无响应,在IMPORT之后好长时间没反应,一点击就无响应,使用器件就没有保障,遂选择一个类似的,唯一是把其中的固件库文件要修改其中一部分好比来说,选择FLASH有不同,那就改变FLASH文件,ADC位数不同,那就该调整STM32L0XX_ADC.H
/**
******************************************************************************
* @file STM32L0xx_flash.h
* @author MCD Application Team
* @version V1.3.0
* @date 16-January-2014
* @brief This file contains all the functions prototypes for the FLASH
* firmware library.
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L0XX_FLASH_H
#define __STM32L0XX_FLASH_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "STM32L0xx.h"
/** @addtogroup STM32L0xx_StdPeriph_Driver
* @{
*/
/** @addtogroup FLASH
* @{
*/
/* Exported types ------------------------------------------------------------*/
/**
* @brief FLASH Status
*/
typedef enum
{
FLASH_BUSY = 1,
FLASH_ERROR_WRP,
FLASH_ERROR_PROGRAM,
FLASH_COMPLETE,
FLASH_TIMEOUT
}FLASH_Status;
/* Exported constants --------------------------------------------------------*/
/** @defgroup FLASH_Exported_Constants
* @{
*/
/** @defgroup FLASH_Latency
* @{
*/
#define FLASH_Latency_0 ((uint32_t)0x00000000) /*!< FLASH Zero Latency cycle */
#define FLASH_Latency_1 FLASH_ACR_LATENCY /*!< FLASH One Latency cycle */
#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \
((LATENCY) == FLASH_Latency_1))
/**
* @}
*/
/** @defgroup FLASH_Interrupts
* @{
*/
#define FLASH_IT_EOP FLASH_CR_EOPIE /*!< End of programming interrupt source */
#define FLASH_IT_ERR FLASH_CR_ERRIE /*!< Error interrupt source */
#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFFEBFF) == 0x00000000) && (((IT) != 0x00000000)))
/**
* @}
*/
#define OB_STOP_NoRST ((uint8_t)0x02) /*!< No reset generated when entering in STOP */
#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */
#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST))
。。。
/** @defgroup FLASH_Option_Bytes_BOOT0SW
* @{
*/
#define OB_BOOT0_SW ((uint8_t)0x00) /*!< BOOT0 pin disabled */
#define OB_BOOT0_HW ((uint8_t)0x80) /*!< BOOT0 pin bonded with GPIO */
#define IS_OB_BOOT0SW(BOOT0) (((BOOT0) == OB_BOOT0_SW) || ((BOOT0) == OB_BOOT0_HW))
/**
* @}
*/
/** @defgroup FLASH_Option_Bytes_VDDA_Analog_Monitoring
* @{
*/
#define OB_VDDA_ANALOG_ON ((uint8_t)0x20) /*!< Analog monitoring on VDDA Power source ON */
#define OB_VDDA_ANALOG_OFF ((uint8_t)0x00) /*!< Analog monitoring on VDDA Power source OFF */
#define IS_OB_VDDA_ANALOG(ANALOG) (((ANALOG) == OB_VDDA_ANALOG_ON) || ((ANALOG) == OB_VDDA_ANALOG_OFF))
/**
* @}
*/
/** @defgroup FLASH_Option_Bytes_SRAM_Parity_Enable
* @{
*/
#define OB_SRAM_PARITY_SET ((uint8_t)0x00) /*!< SRAM parity enable Set */
#define OB_SRAM_PARITY_RESET ((uint8_t)0x40) /*!< SRAM parity enable reset */
#define IS_OB_SRAM_PARITY(PARITY) (((PARITY) == OB_SRAM_PARITY_SET) || ((PARITY) == OB_SRAM_PARITY_RESET))
/**
* @}
*/
/** @defgroup FLASH_Flags
* @{
*/
#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */
#define FLASH_FLAG_PGERR FLASH_SR_PGERR /*!< FLASH Programming error flag */
#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Programming flag */
#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCB) == 0x00000000) && ((FLAG) != 0x00000000))
#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_PGERR) || \
((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_EOP))
#ifdef __cplusplus
}
#endif
#endif
接着是IAR的工程项目
选择你要新建的工程的编程语言,有汇编,C,C++三种。 接着在工程选项中选择对应设备 接着按照普通KEIL工程文件夹格式建立文件 |
2.开发板特性的探究举例
STM32L053R8是基于ARM Cortex-M0+内核的超低功耗32位MCU,集成了多达64KB闪存,8KB SRAM,2KB EEPROM以及LCD,USB,ADC和DAC等性能,为0.95 DMIPS/MHz
我们一起学习一下开发板的AD,DA在MBED下的编程:
其中肉色的是ADC通道,而MBED的ADC编程也是非常简单,
#include "mbed.h"
AnalogIn analog_value(A0);
Serial pc(SERIAL_TX, SERIAL_RX);
int main() {
while(1) {
uint16_t meas = analog_value.read_u16(); // Converts and read the analog input value
pc.printf("%d\n",meas);
}
用起来非常简单,具体你想要那个AnalogIn ,就在声明时写哪个。
我链接的端口输出是这样的:
接着我们使用RTC来打印一下时间:首先来说一下基本概念
RTC由两个主要部分组成。第一部分(APB1接口)用来和 APB1总线相连。此单元还包含一组 16位寄存器,可通过 APB1总线对其进行读写操作。APB1接口以 APB1总线时钟为时钟,用来与 APB1总线接口。
另一部分(RTC核)由一系列可编程计数器组成,分成两个主要模块。第一个模块是 RTC的预分频模块,它可编程产生最长为 1秒的 RTC时间基准 TR_CLK。RTC的预分频模块包含了一个 20位的可编程分频器(RTC预分频器)。在每个TR_CLK周期中,如果在 RTC_CR 寄存器中设置了相应允许位,则 RTC产生一个中断(秒中断)。第 2个模块是一个 32位的可编程的计数器,它可被初始化为当前的系统时间。系统时间以 TR_CLK速度增长并与存储在 RTC_ALR寄存器中的可编程的时间相比较,如果 RTC_CR控制寄存器中设置了相应允许位,则比较匹配时将产生一个闹钟中断。
RTC初始化程序
void RTC_configuration()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);//使能RTC后备寄存器的写
BKP_DeInit();//BKP寄存器全部设为缺省值
RCC_LSEConfig(RCC_LSE_ON); //RCC打开了LSE时钟
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);//等待LSE就绪,一般来说,如果谐振不对,就会死在这里,实际代码请慎重
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//RTC使用时钟源LSE
RCC_RTCCLKCmd(ENABLE);//RTC的时钟开启
RTC_WaitForSynchro();//RTC等待同步,
RTC_WaitForLastTask();//这个代码在RTC中常常出现,类似于等待就绪的含义
//RTC_ITConfig(RTC_IT_SEC, ENABLE);//RTC秒中断
RTC_WaitForLastTask();//
RTC_SetPrescaler(32767);//RTC预分频,32768HZ,分为一秒一个振荡,RTC period = RTCCLK/RTC_PR = (32.768KHz)/(32767+1)
RTC_WaitForLastTask(); //等待同步
PWR_BackupAccessCmd(DISABLE);//禁止RTC后备寄存器的写
}
MBED的程序:
#include "mbed.h"
Serial pc(SERIAL_TX, SERIAL_RX);
DigitalOut myled(LED1);
int main() {
pc.printf("RTC example\n");
set_time(1387188323); // Set RTC time to 16 December 2013 10:05:23 UTC
pc.printf("Date and time are set.\n");
while(1) {
time_t seconds = time(NULL);
//printf("Time as seconds since January 1, 1970 = %d\n", seconds);
pc.printf("Time as a basic string = %s", ctime(&seconds));
//char buffer[32];
//strftime(buffer, 32, "%I:%M:%S %p\n", localtime(&seconds));
//printf("Time as a custom formatted string = %s", buffer);
myled = !myled;
wait(1);
}
}
接着我们来驱动一下ILI4系列的显示屏:
#include "mbed.h"
SPI device(SPI_MOSI, SPI_MISO, SPI_SCK);
其中SPI_MOSI对应你的开发板上面的默认的MOSI,MISO,SCK引脚
//这是我的板子上面的引脚分布图,SPI协议引脚都有在上面
typedef unsigned char uchar;
typedef unsigned int uint;
DigitalOut rs(D10);
//RS,是这种液晶屏幕的一个重要引脚,也常常标记为PC
DigitalOut cs(D9);
//CS与片选使能还是有一定区别
DigitalOut reset(D8);
//RESET复位引脚
uchar bitdata;
void delay(uint t);
延时函数
void delay(uint time)
{
uint i,j;
for(i=0;i<time;i++)
for(j=0;j<2500;j++);
}
写命令
void write_command(uchar c)
{
cs=0;
rs=0;
bitdata=c;
device.write(bitdata);
cs=1;
}
写数据
void write_data(uchar d)
{
cs=0;
rs=1;
bitdata=d;
device.write(bitdata);
cs=1;
}
写16位数据
void wr_com16(unsigned char i,unsigned char j)
{
cs=0;
rs=1;
bitdata=i;
device.write(bitdata);
cs=1;
cs=0;
rs=1;
bitdata=j;
device.write(bitdata);
cs=1;
}
写命令与数据
void LCD_Write_COM_DATA(uchar i,uint j)
{
write_command(i);
wr_com16(j>>8,j);
}
初始化液晶屏幕
void lcd_initial()
{
reset=0;
delay(100);
reset=1;
delay(100);
LCD_Write_COM_DATA(0x10, 0x0000); // Set SAP,DSTB,STB
LCD_Write_COM_DATA(0x11, 0x0000); // Set APON,PON,AON,VCI1EN,VC
LCD_Write_COM_DATA(0x12, 0x0000); // Set BT,DC1,DC2,DC3
LCD_Write_COM_DATA(0x13, 0x0000); // Set GVDD
LCD_Write_COM_DATA(0x14, 0x0000); // Set VCOMH/VCOML voltage
delay(40); // Delay 20 ms
// Please follow this power on sequence
LCD_Write_COM_DATA(0x11, 0x0018); // Set APON,PON,AON,VCI1EN,VC
LCD_Write_COM_DATA(0x12, 0x1121); // Set BT,DC1,DC2,DC3
LCD_Write_COM_DATA(0x13, 0x0063); // Set GVDD
LCD_Write_COM_DATA(0x14, 0x3961); // Set VCOMH/VCOML voltage
LCD_Write_COM_DATA(0x10, 0x0800); // Set SAP,DSTB,STB
delay(10); // Delay 10 ms
LCD_Write_COM_DATA(0x11, 0x1038); // Set APON,PON,AON,VCI1EN,VC
delay(30); // Delay 30 ms
LCD_Write_COM_DATA(0x02, 0x0100); // set 1 line inversion
//R01H:SM=0,GS=0,SS=1 (for details,See the datasheet of ILI9225)
LCD_Write_COM_DATA(0x01, 0x011C); // set the display line number and display direction
//R03H:BGR=1,ID0=1,ID1=1,AM=0 (for details,See the datasheet of ILI9225)
LCD_Write_COM_DATA(0x03, 0x1030); // set GRAM write direction.
LCD_Write_COM_DATA(0x07, 0x0000); // Display off
LCD_Write_COM_DATA(0x08, 0x0808); // set the back porch and front porch
LCD_Write_COM_DATA(0x0B, 0x1100); // set the clocks number per line
LCD_Write_COM_DATA(0x0C, 0x0000); // CPU interface
LCD_Write_COM_DATA(0x0F, 0x0501); // Set Osc
LCD_Write_COM_DATA(0x15, 0x0020); // Set VCI recycling
LCD_Write_COM_DATA(0x20, 0x0000); // RAM Address
LCD_Write_COM_DATA(0x21, 0x0000); // RAM Address
//------------------------ Set GRAM area --------------------------------//
LCD_Write_COM_DATA(0x30, 0x0000);
LCD_Write_COM_DATA(0x31, 0x00DB);
LCD_Write_COM_DATA(0x32, 0x0000);
LCD_Write_COM_DATA(0x33, 0x0000);
LCD_Write_COM_DATA(0x34, 0x00DB);
LCD_Write_COM_DATA(0x35, 0x0000);
LCD_Write_COM_DATA(0x36, 0x00AF);
LCD_Write_COM_DATA(0x37, 0x0000);
LCD_Write_COM_DATA(0x38, 0x00DB);
LCD_Write_COM_DATA(0x39, 0x0000);
// ---------- Adjust the Gamma 2.2 Curve -------------------//
LCD_Write_COM_DATA(0x50, 0x0603);
LCD_Write_COM_DATA(0x51, 0x080D);
LCD_Write_COM_DATA(0x52, 0x0D0C);
LCD_Write_COM_DATA(0x53, 0x0205);
LCD_Write_COM_DATA(0x54, 0x040A);
LCD_Write_COM_DATA(0x55, 0x0703);
LCD_Write_COM_DATA(0x56, 0x0300);
LCD_Write_COM_DATA(0x57, 0x0400);
LCD_Write_COM_DATA(0x58, 0x0B00);
LCD_Write_COM_DATA(0x59, 0x0017);
LCD_Write_COM_DATA(0x0F, 0x0701); // Vertical RAM Address Position
LCD_Write_COM_DATA(0x07, 0x0012); // Vertical RAM Address Position
delay(50); // Delay 50 ms
LCD_Write_COM_DATA(0x07, 0x1017); // Vertical RAM Address Position
}
设置显示位置的命令
void addset(unsigned int x,unsigned int y)
{
LCD_Write_COM_DATA(0x20,x);
//write_command(0x20);
// LCD_Write_COM_DATA(0x36,x);
//wr_com16(x>>8,x);
LCD_Write_COM_DATA(0x21,y);
//write_command(0x21);
// LCD_Write_COM_DATA(0x36,x);
//wr_com16(y>>8,y);
write_command(0x22);
}
显示区域设置命令
void Lcd_SetRegion(uchar xStar, uchar yStar,uchar xEnd,uchar yEnd)
{
LCD_Write_COM_DATA(0x36,xEnd);
LCD_Write_COM_DATA(0x37,xStar);
LCD_Write_COM_DATA(0x38,yEnd);
LCD_Write_COM_DATA(0x39,yStar);
LCD_Write_COM_DATA(0x20,xStar);
LCD_Write_COM_DATA(0x21,yStar);
write_command(0x22);
}
屏幕清除命令
void Lcd_Clear(uchar DH,uchar DL)
{
unsigned int i,m;
Lcd_SetRegion(0,0,175,219);
for(i=0;i<175;i++)
for(m=0;m<219;m++)
{
wr_com16(DH,DL);
}
}
int main() {
lcd_initial();
Lcd_Clear(0x07,0xe0);//绿色
/*RGB
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define WHITE 0xffff
#define BLACK 0x0000
#define YELLOW 0xFFE0
#define GRAY0 0xEF7D
#define GRAY1 0x8410
#define GRAY2 0x4208
*/
while(1);
{}
}
顺便写一个OLED的屏幕的测试程序,大家可以借鉴一下:
void OLED_Init(void)
{
OLED_RST=0;
DelayMs(50);
OLED_RST=1; //从上电到下面开始初始化要有足够的时间,即等待RC复位完毕
OLED_WrCmd(0xae);//--turn off oled panel
OLED_WrCmd(0x00);//---set low column address
OLED_WrCmd(0x10);//---set high column address
OLED_WrCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WrCmd(0x81);//--set contrast control register
OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
OLED_WrCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WrCmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WrCmd(0xa6);//--set normal display
OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
OLED_WrCmd(0x3f);//--1/64 duty
OLED_WrCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WrCmd(0x00);//-not offset
OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WrCmd(0xd9);//--set pre-charge period
OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WrCmd(0xda);//--set com pins hardware configuration
OLED_WrCmd(0x12);
OLED_WrCmd(0xdb);//--set vcomh
OLED_WrCmd(0x40);//Set VCOM Deselect Level
OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WrCmd(0x02);//
OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
OLED_WrCmd(0x14);//--set(0x10) disable
OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
OLED_WrCmd(0xaf);//--turn on oled panel
OLED_Fill(0x00); //初始清屏
OLED_SetPos(0,0);
}
/*********************OLED写数据************************************/
void OLED_WrDat(unsigned char dat)
{
unsigned char i;
OLED_DC=1;
for(i=0;i<8;i++) //发送一个八位数据
{
if((dat << i) & 0x80)
{
OLED_SDA = 1;
}
else OLED_SDA = 0;
OLED_SCL = 0;
OLED_SCL = 1;
}
}
/*********************OLED写命令************************************/
void OLED_WrCmd(unsigned char cmd)
{
unsigned char i;
OLED_DC=0;
for(i=0;i<8;i++) //发送一个八位数据
{
if((cmd << i) & 0x80)
{
OLED_SDA = 1;
}
else
{
OLED_SDA = 0;
}
OLED_SCL = 0;
OLED_SCL = 1;
}
}