一、項目配置
1、新建項目文件夾"TimSeg";
2、通過Keil5創建新項目,保存在所創建的文件夾中(設項目名為pTimSeg),選擇MCU芯片為"STM32F103ZE"(本程序使用的硬件為:STM32-PZ6806L開發板)
3、在"TimSeg"文件夾下新建"CMSIS"、"Device"、"Public"、"Startup"、"User"和"Lib"文件夾。
① 在"CMSIS"文件夾中復制"core_cm3.h"和"core_cm3.c"文件;
② 在" Device "文件夾中復制"stm32f10x.h"、"system_stm32f10x.h"和"system_stm32f10x.c"文件;
③ 在" Startup "文件夾中復制"startup_stm32f10x_hd.s"文件;
④在"Lib"文件夾中新建"inc"和"src"兩個子文件夾,在"inc"文件夾中復制"misc.h"、"stm32f10x_gpio.h"、"stm32f10x_tim.h"和"stm32f10x_rcc.h"文件;在"src"文件夾中復制"misc.c"、"stm32f10x_gpio.c"、"stm32f10x_tim.c"和"stm32f10x_rcc.c"文件;
4、為項目添加"CMSIS"、"Device"、"Public"、"Startup"、"User"和"Lib"組,并將上述C程序文件和"startup_stm32f10x_hd.s"啟動文件加入到相應組中。
5、打開“項目配置”對話框,在"Output"選項卡中選擇"Create HEX File",在"C/C++"選項卡中的"Include Paths"中添加如下包含路徑:".CMSIS;", ".Device;", ".Libinc;",".Public;"。
6、在"stm32f10x.h"中添加函數參數檢查宏
(參看:https://blog.csdn.net/fanxp66/article/details/80215090)
#ifdef USE_FULL_ASSERT
/**
* @brief 這個assert_param宏用于函數參數檢查
* @param expr:如果expr是 false,就調用 assert_failed函數報告源文件名和
* 失敗的行號,如果expr是 true ,就返回一個空值
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
7、新建一個文件(system.h),保存到"Public"文件夾中,內容為:
#ifndef __SYSTEM__H
#define __SYSTEM__H
#include "stm32f10x.h"
//定義位帶地址宏
#define BITBAND(addr,bitnum) ((addr&0xF0000000) + 0x02000000 + ((addr&0x000FFFFF)<<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)
#define GPIOB_ODR_Addr (GPIOB_BASE + 12)
#define GPIOC_ODR_Addr (GPIOC_BASE + 12)
#define GPIOD_ODR_Addr (GPIOD_BASE + 12)
#define GPIOE_ODR_Addr (GPIOE_BASE + 12)
#define GPIOF_ODR_Addr (GPIOF_BASE + 12)
#define GPIOG_ODR_Addr (GPIOG_BASE + 12)
//數據輸入寄存器地址
#define GPIOA_IDR_Addr (GPIOA_BASE + 12)
#define GPIOB_IDR_Addr (GPIOB_BASE + 12)
#define GPIOC_IDR_Addr (GPIOC_BASE + 12)
#define GPIOD_IDR_Addr (GPIOD_BASE + 12)
#define GPIOE_IDR_Addr (GPIOE_BASE + 12)
#define GPIOF_IDR_Addr (GPIOF_BASE + 12)
#define GPIOG_IDR_Addr (GPIOG_BASE + 12)
#endif
該文件定義了GPIO端口位帶操作的宏。
二、數碼管電路與使用配置
開發板上數碼管相關電路如下圖所示:
要使得數碼管正常顯示需要進過以下步驟:
1、使能GPIOC時鐘
2、配置GPIOC_0-GPIOC_7為推挽輸出,50MHz速度
3、通過庫函數操作控制輸出
4、實現過程
① 在上述配置的項目中添加"seg.h"和"seg.c"文件,保存在"User/Seg"文件夾下,"seg.h"文件的內容為:
#ifndef __SEG__H
#define __SEG__H
#include "system.h"
#include "stm32f10x_gpio.h"
#define SEGPORT GPIOC
#define SEG_RCCPORT RCC_APB2Periph_GPIOC
#define SEGPIN (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7)
void Seg_Init(void);
#endif
"seg.c"文件的內容為:
#include "seg.h"
#include "stm32f10x_rcc.h"
void Seg_Init()
{
GPIO_InitTypeDef GPIOC_mode;
RCC_APB2PeriphClockCmd(SEG_RCCPORT, ENABLE);
GPIOC_mode.GPIO_Pin = SEGPIN;
GPIOC_mode.GPIO_Speed = GPIO_Speed_50MHz;
GPIOC_mode.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SEGPORT, &GPIOC_mode);
}
void Show()
{
static u8 n=0;
u16 seg[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
GPIO_Write(SEGPORT, seg[n]);
n++;
n = n%10;
}
② 將"seg.c"文件添加到項目的"User"組中;
③ 將"./User/Seg"路徑添加到項目文件包含的配置路徑中(在"C/C++"選項卡中的"Include Paths"中)。
三、定時器TIM1配置
1、選擇定時器
使用定時器首先要選擇定時器,stm32f103zet6MCU芯片有8個定時器,其中TIM1和TIM8稱為高級定時器,TIM2-TIM5稱為通用定時器,TIM6和TIM7稱為基本定時器,這里選擇TIM1作為通用定時器功能使用。
2、計算定時器配置參數
在本程序中,想要通過TIM1進行1秒的定時,實現每秒鐘產生一次定時計數溢出中斷,然后在中斷函數中調用數碼管顯示輸出。由于系統初始化時鐘(調用SystemInit函數)后APB2總線上的時鐘為72MHz,本程序中TIM1的時鐘選擇為CK_INT,為72MHz,這個頻率進過預分頻和計數后得到1秒的定時,需要設置預分頻系數與定時計數值之積為72M,這里設置預分頻系數為7200,計數器計數值為10000。
3、計數器配置編程
① 使能TIM1時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE );
② 配置TIM1參數
typedef struct
{
uint16_t TIM_Prescaler; /*預分頻系數. 取值0x0000-0xFFFF */
uint16_t TIM_CounterMode; /*計數模式*/
uint16_t TIM_Period; /*計數值 0x0000到 0xFFFF. */
uint16_t TIM_ClockDivision; /*!時鐘分割,用于數字濾波器*/
uint8_t TIM_RepetitionCounter; /*重復次數,僅對TIM1和TIM8有意義.
} TIM_TimeBaseInitTypeDef;
計數模式定義:
#define TIM_CounterMode_Up ((uint16_t)0x0000)
#define TIM_CounterMode_Down ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
時鐘分割
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
程序如下:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定義配置結構體變量
TIM_TimeBaseStructure.TIM_Prescaler = (7200– 1);
TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = (10000 –1);
TIM_TimeBaseStructure.TIM_ClockDivision =0;
TIM_TimeBaseStructure.TIM_RepetitionCounter= 0;
TIM_TimeBaseInit( TIM1,&TIM_TimeBaseStructure);
③ 設置定時器中斷類型,并使能。
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
④ 開啟計數器,開始計數
TIM_Cmd( TIM1, ENABLE);
4、實現步驟
① 在上述配置的項目中添加"tim.h"和"tim.c"文件,保存在"User/Tim"文件夾下,"tim.h"文件的內容為:
#ifndef __TIM__H
#define __TIM__H
#include "system.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"
void Init_Tim(void);
#endif
"tim.c"文件內容為:
#include "tim.h"
void Tim_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定義配置結構體變量
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );//使能定時器TIM1時鐘
TIM_TimeBaseStructure.TIM_Prescaler = (7200-1);
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = (10000-1);
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseStructure);
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);//清除TIM1溢出中斷標志
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//打開溢出中斷
TIM_Cmd( TIM1, ENABLE); //啟動定時器
}
② 將"tim.c"文件添加到項目的"User"組中;
③ 將"./User/Tim"路徑添加到項目文件包含的配置路徑中(在"C/C++"選項卡中的"Include Paths"中)。
四、NVIC配置和中斷函數
1、配置中斷分組(NVIC)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
2、使能中斷
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel =TIM1_UP_IRQn; //定時器1上溢中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0; //主優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init( & NVIC_InitStructure);
3、實現步驟
① 在上述配置的項目中添加"nvic.h"和"nvic.c"文件,保存在"User/Nvic"文件夾下,"nvic.h"文件的內容為:
#ifndef __NVIC__H
#define __NVIC__H
#include "stm32f10x.h"
#include "misc.h"
void My_NVIC_Init(void);
#endif
"nvic.c"文件內容為:
#include "nvic.h"
void My_NVIC_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //定時器TIM1上溢中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( & NVIC_InitStructure);
}
② 將"nvic.c"文件添加到項目的"User"組中;
③ 將"./User/Nvic"路徑添加到項目文件包含的配置路徑中(在"C/C++"選項卡中的"Include Paths"中)。
五、主函數和終端服務函數
在main.c中添加中斷服務函數TIM1_UP_IRQHandler,修改主函數,內容如下:
#include "seg.h"
#include "tim.h"
#include "nvic.h"
int main()
{
Seg_Init();
My_NVIC_Init();
Tim_Init();
Show();
while(1)
上一篇:STM32串口通信之Hello(STM32_11)
下一篇:STM32外部中斷方式按鍵操作(STM32_09)
推薦閱讀
史海拾趣
以下是關于DENWIRE公司在電子行業中發展起來的五個相關故事,每個故事都遵循了字數和事實性的要求。
故事一:
DENWIRE公司起初只是一家小型的電線制造商,專注于生產低端音頻線纜。然而,隨著科技的進步和消費者對于音頻質量的追求,公司創始人李先生看到了高品質音頻線纜市場的潛力。他帶領團隊投入大量研發資源,成功開發出了一款具有極低信號損失和出色耐用性的音頻線纜,贏得了市場的廣泛認可。這款產品不僅讓DENWIRE在音頻線纜領域嶄露頭角,也為公司后續的發展奠定了堅實的基礎。
故事二:
隨著公司規模的擴大,DENWIRE逐漸涉足到了數據傳輸線纜的生產。在面對激烈市場競爭時,公司堅持創新驅動,注重產品質量。在一次與知名科技公司的合作中,DENWIRE憑借其出色的產品性能和可靠的品質,成功贏得了對方的信任,并簽訂了長期供貨合同。這次合作不僅為DENWIRE帶來了可觀的收益,也進一步提升了公司在行業內的知名度。
故事三:
在新能源汽車行業蓬勃發展的背景下,DENWIRE敏銳地捕捉到了這一領域的商機。公司迅速調整戰略方向,加大了對新能源汽車用線纜的研發和生產投入。經過多次試驗和改進,DENWIRE成功開發出了一款符合新能源汽車高標準要求的線纜產品,并在市場上取得了良好的銷售業績。這一成就不僅彰顯了DENWIRE的技術實力,也為公司未來的發展開辟了新的道路。
故事四:
面對全球化市場的挑戰,DENWIRE積極尋求國際合作與拓展。公司先后與多個國家和地區的知名企業建立了戰略合作關系,共同開發新產品、拓展新市場。通過國際合作,DENWIRE不僅學習到了先進的生產技術和管理經驗,也進一步提升了自身的品牌影響力和市場競爭力。
故事五:
在環保和可持續發展成為全球共識的背景下,DENWIRE積極響應號召,致力于推動綠色生產和可持續發展。公司投入大量資金引進環保設備和工藝,優化生產流程,減少能源消耗和廢棄物排放。同時,DENWIRE還積極參與社會公益活動,回饋社會。這些舉措不僅提升了公司的社會形象,也為公司的長期發展注入了新的活力。
DIOFIT公司一直秉持著品質至上的生產理念,注重產品質量和用戶體驗。他們嚴格控制原材料采購和生產流程,確保每一款產品都符合高標準的質量要求。同時,DIOFIT公司還建立了完善的售后服務體系,及時解決用戶在使用過程中遇到的問題,贏得了用戶的信賴和好評。
在市場競爭日益激烈的情況下,DIOFIT公司憑借敏銳的市場洞察力和靈活的營銷策略,不斷拓展市場份額。他們針對不同地區、不同行業的需求,制定個性化的產品推廣方案,通過線上線下相結合的方式,加強品牌推廣和渠道建設。同時,DIOFIT公司還積極參與各類展會和論壇,與業界同仁交流合作,拓展國際視野,為公司的發展注入新的活力。
在國內市場取得一定成績后,銓力公司開始將目光轉向國際市場。通過參加國際展覽、與海外客戶建立合作關系等方式,公司逐漸打開了海外市場的大門。同時,銓力還積極尋求與國際知名企業的合作機會,通過技術交流和資源整合,不斷提升自身的技術水平和市場競爭力。
EMMICRO公司始終將產品質量視為企業的生命線。公司建立了嚴格的質量管理體系,從原材料采購到生產流程,再到成品檢驗,每一個環節都嚴格把控,確保產品的品質穩定可靠。這種對品質的執著追求贏得了客戶的信任和好評,也為公司贏得了更多的市場份額。
作為一家具有社會責任感的企業,EMMICRO公司始終關注環保和社會公益事業。公司積極參與環保活動和公益捐贈,推動企業的可持續發展和社會進步。同時,公司還積極承擔對員工的培訓和發展責任,為員工提供良好的職業發展平臺和福利待遇。這種對社會責任的擔當也贏得了社會的廣泛贊譽和尊重。
請推薦個JTAG仿真器 我們在用合眾達seed-vpm642的板子,但沒有JTAG仿真器,請大家給推薦個支持TMS320DM642的國內廠商的仿真器,謝謝大家!… 查看全部問答∨ |
|
本帖最后由 paulhyde 于 2014-9-15 09:03 編輯 誰有關于這個設計的電路圖,請發給我好嗎?不勝感激!!! 郵箱:fangqun188@163.com … 查看全部問答∨ |
鋰離子電池因高能量密度的特點越來越受到人們的歡迎。但是,再強勁的鋰離子電池也有能量耗盡的一刻,只有跟充電器完美的配合,它才能發揮最大潛能。于是,在鋰離子電池大放異彩的今天,充電器芯片也得到了越來越多的關注。 多方面的挑戰 ...… 查看全部問答∨ |
WinCE中,基于對話框的程序,怎樣擁有唯一的窗口類? 為了取得窗口句柄 兩個基于對話框的程序, GetClassName取得的窗口類名都是Dialog,兩個窗口都沒有標題,所以不能通過窗口標題,使用FindWindow取得窗口句柄。那么怎樣取得窗口句柄?… 查看全部問答∨ |
我下了個電池驅動,希望在電量改變的時候WinCE有消息提示,我現在發現在BatteryPDDGetStatus函數中置gpStatus->fChanged為TRUE,第一次是可以彈出電量低的消息的,但是后面就不再提示了,在串口上有類似如下的消息發出: 0x83b04400: Received power n ...… 查看全部問答∨ |
我使用的是 AnyDATA CDMA DTGS800-6025模塊 接收短信提前設置 AT+UGSM=1(使用第二套短信接口) AT+CMGF=0(普通編碼輸出格式) AT+CMGR=0 接收第一條短信.模塊的輸出內容是 13 10 43 67 77 71 82 58 32 48 48 48 48 48 50 51 ...… 查看全部問答∨ |
|