網(wǎng)上有很多關(guān)于pos機(jī)操作手冊(cè)下載,STM32F103C8T6制作舵機(jī)測試儀詳細(xì)圖文教程的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)操作手冊(cè)下載的問題,今天pos機(jī)之家(www.rcqwhg.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來看下吧!
本文目錄一覽:
pos機(jī)操作手冊(cè)下載
自主學(xué)習(xí)stm32已有一周,先實(shí)現(xiàn)一個(gè)小demo,算是給自己一個(gè)動(dòng)力叭,有目標(biāo)的學(xué)習(xí)收獲會(huì)更多。雖然本科也修了嵌入式課程,但那種走馬觀花式的學(xué)習(xí),最后真正得到的知識(shí)實(shí)在寥寥無幾。個(gè)人理解,學(xué)習(xí)STM32不只是學(xué)習(xí)編程,更多的是學(xué)習(xí)查資料、查數(shù)據(jù)手冊(cè)、軟件的使用和調(diào)試方法上,真正需要自己從頭造的部分不是很多,吸取前人的經(jīng)驗(yàn),搬過來取自己所需即可。用農(nóng)夫山泉的話來說就是,我們不生產(chǎn)代碼,我們只是代碼的搬運(yùn)工!
這次主要跟著正點(diǎn)原子的開發(fā)資料進(jìn)行學(xué)習(xí),沒有使用戰(zhàn)艦開發(fā)板,而是使用STM32F103C8T6板子。一是避免自己直接把例程的代碼燒進(jìn)開發(fā)板,最后啥也沒學(xué)到,在不同的板子間移植代碼過程中,能夠掌握理解更多的基礎(chǔ)知識(shí)和調(diào)試經(jīng)驗(yàn);二是這個(gè)小板子廉價(jià)易得,只要十塊錢,和大幾百的開發(fā)板相比,它體積小、資源可觀,很適合我的小項(xiàng)目,以后準(zhǔn)備用來制作航模遙控器,敬請(qǐng)關(guān)注哈~
1.材料清單1.STM32F103C8T6藍(lán)色開發(fā)板*1(黑色板也可以)
2.USB轉(zhuǎn)TTL模塊*1
3. ST-LINK V2仿真器下載器*1(調(diào)試STM32性價(jià)比極高)
4. OLED屏幕(4管腳)*1
5.10k電位器*1(10k以上都可)
6. 杜邦線、面包板、導(dǎo)線、插針若干
2.電路連接電位器:GND - PA0 - 3.3VOLED顯示屏:GND 電源地VCC 接3.3v電源SCL 接PB8(SCL)SDA 接PB9(SDA)
ST-LINK V2接法:GND 電源地3V3 接3.3vSWCLK 接DCLKSWDIO 接DIO串口USB-TTL接法:GND 電源地3V3 接3.3vTXD 接PB7RXD 接PB6PWM輸出:PB5
實(shí)物連接圖如下:
3.安裝keil5安裝及破解MDK(Keil5)教程 https://blog.csdn.net/weixin_42911200/article/details/81590158
注意要安裝keil.STM32F1xx_DFP.2.3.0.pack支持包,因?yàn)槲覀円肧TM32F103C8T6芯片的庫函數(shù)編寫。
庫下載地址:https://www.keil.com/dd2/Pack/
博主已上傳天翼云盤:https://cloud.189.cn/t/vyUBFzyuMBZr(訪問碼:6sng)
等待網(wǎng)頁加載完,在列表里找到Keil,再找STMicroelectronics STM32F1 Series Device Support, Drivers and
4.新建工程新建keil庫函數(shù)工程 https://www.cnblogs.com/zeng-1995/p/11308622.html
與鏈接里面不同的是以下幾個(gè)設(shè)置:
點(diǎn)擊圖標(biāo)按鈕1,打開Manage Run-Time Environment窗口,Device如下勾選,其他欄與鏈接中相同;
點(diǎn)擊圖標(biāo)按鈕2,打開Manage Project Items窗口,Groups和 Files如下設(shè)置:
點(diǎn)擊圖標(biāo)按鈕3,打開Options for Target窗口,點(diǎn)擊頂部菜單按鈕切換子窗口,依次如下設(shè)置:
點(diǎn)擊Setting,打開Cortex-M Target Driver Setup窗口,如果SWDIO里面未顯示序列號(hào),則電腦需要更新ST-LINK驅(qū)動(dòng)。
解決方法見鏈接 https://blog.csdn.net/qq_42041980/article/details/92015997
5.程序?qū)崿F(xiàn)控制舵機(jī)的PWM:周期20ms,高電平時(shí)間0.5ms~2.5ms變化,可控制舵機(jī)0~180°的角度變化,即每個(gè)高電平時(shí)間都對(duì)應(yīng)舵機(jī)的一個(gè)角度。但航模舵面的實(shí)際控制中,不可能有180°變化,所以通用的高電平寬度其實(shí)是1ms~2ms。
具體可參考https://www.moz8.com/forum.php?mod=viewthread&tid=82875&highlight=舵機(jī)測試儀
控制無刷電調(diào)所用的PWM信號(hào)高電平時(shí)間也是1ms~2ms,所以我們要實(shí)現(xiàn)的PWM信號(hào)周期20ms,高電平時(shí)間1ms~2ms。
我們使用ADC1讀取電位器的電壓采樣值,并從0~4095范圍的采樣值轉(zhuǎn)換到1000~2000,賦值給PWM輸出。TIM2定時(shí)觸發(fā)ADC采樣,通過DMA傳輸給變量所在的寄存器,取10次進(jìn)行均值濾波,消除抖動(dòng)。定時(shí)器觸發(fā)ADC,DMA傳輸 http://www.openedv.com/forum.php?mod=viewthread&tid=277863&extra=&page=1
定時(shí)器TIM觸發(fā)ADC采樣,DMA搬運(yùn)到內(nèi)存 https://blog.csdn.net/qq_38410730/article/details/89921413
TIM3定時(shí)觸發(fā)產(chǎn)生PWM信號(hào),預(yù)分頻72,頻率1MHz,周期1us;自動(dòng)裝載值20 000,故PWM周期1us*20 000=20ms。主要代碼如下:
main.c文件-包含程序說明、主函數(shù)
/*=============舵機(jī)測試儀==============芯片STM32F103C8T6,使用ADC讀取電位器的電壓采樣值,0~4095轉(zhuǎn)換到1000~2000,賦值給PWM輸出。 TIM2定時(shí)觸發(fā)ADC采樣,通過DMA傳輸給變量ch1Value,取10次進(jìn)行均值濾波??刂贫鏅C(jī)的PWM:周期20ms,高電平時(shí)間0.5ms~2.5ms變化,可控制舵機(jī)0~180°的角度變化, 但航模舵面的實(shí)際控制中,不可能有180°變化,所以通用的高電平寬度其實(shí)是1ms~2ms電位器:GND - PA0 - 3.3VOLED顯示屏:GND 電源地VCC 接3.3v電源SCL 接PB8(SCL)SDA 接PB9(SDA)串口USB-TTL接法:GND 電源地3V3 接3.3vTXD 接PB7RXD 接PB6ST-LINK V2接法:GND 電源地3V3 接3.3vSWCLK 接DCLKSWDIO 接DIOPWM輸出:PB5by Bilibili 蔡子CaiZi*/#include "config.h"#include "delay.h"#include "usart.h"#include "stm32f10x.h"#include "oled.h"#include "RTC.h" #include "stdio.h"#include "string.h" int main(){u8 txt[16]={0};delay_init();//初始化延時(shí)函數(shù)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2,2位搶占優(yōu)先級(jí)和2位子優(yōu)先級(jí)usart_init(115200);//初始化串口1,波特率為115200TIM3_PWM_Init(19999,71);//預(yù)分頻72,頻率1MHz,周期1us;自動(dòng)裝載值20 000,故PWM周期1us*20 000TIM2_Init(499,71);//1MHz,每500us采集一次;可設(shè)置9us以上,但過小影響OLED顯示DMA1_Init();//DMA初始化GPIOA_Init();//PA初始化Adc_Init();//ADC初始化RTC_Init(); //RTC初始化OLED_Init();//初始化OLED OLED_Clear(); while (1){itoa(PWM1value,txt,10);//將int類型轉(zhuǎn)換成10進(jìn)制字符串//printf("采樣值:%d\舵量:%s\",ch1Value,txt);//printf("當(dāng)前時(shí)間:%d:%d:%d\",calendar.hour,calendar.min,calendar.sec);//OLED_Clear();//一直清屏?xí)斐砷W爍strcat(txt," us");//合并字符串OLED_ShowString(6,3,txt,24); //位置6,3;字符大小24*24點(diǎn)陣OLED_Refresh_Gram();delay_ms(1);}}
config.c文件-包含TIM/ GPIO/ ADC等初始化函數(shù)
#include "config.h"#include "delay.h"#include "usart.h"#include "sys.h"#include "rtc.h" volatile u16 ch1Value[10];//ADC采樣值volatile u16 PWM1value;//控制PWM占空比#define ADC1_DR_Address ((u32)0x4001244C)//ADC1的地址//通用定時(shí)器2中斷初始化//這里時(shí)鐘選擇為APB1的2倍,而APB1為36M//arr:自動(dòng)重裝值。//psc:時(shí)鐘預(yù)分頻數(shù)//這里使用的是定時(shí)器2控制ADC定時(shí)采樣void TIM2_Init(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //時(shí)鐘使能 //定時(shí)器TIM2初始化TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//根據(jù)指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比較輸出使能TIM_OCInitStructure.TIM_Pulse = 9;//計(jì)數(shù)達(dá)到9產(chǎn)生中斷TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//輸出極性:TIM輸出比較極性低TIM_OC2Init(TIM2, & TIM_OCInitStructure);//初始化外設(shè)TIM2_CH2TIM_Cmd(TIM2, ENABLE); //使能TIMxTIM_CtrlPWMOutputs(TIM2, ENABLE); } //DMA1配置void DMA1_Init(void){DMA_InitTypeDef DMA_InitStructure;NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能ADC1通道時(shí)鐘//DMA1初始化DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC1地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ch1Value; //ch1Value的內(nèi)存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向(從外設(shè)到內(nèi)存)DMA_InitStructure.DMA_BufferSize = 10; //DMA緩存大小,存放10次采樣值DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)地址固定,接收一次數(shù)據(jù)后,設(shè)備地址禁止后移DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存地址不固定,接收多次數(shù)據(jù)后,目標(biāo)內(nèi)存地址后移DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord ; //外設(shè)數(shù)據(jù)單位,定義外設(shè)數(shù)據(jù)寬度為16位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord ; //內(nèi)存數(shù)據(jù)單位,HalfWord就是為16位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //DMA模式:循環(huán)傳輸DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //DMA優(yōu)先級(jí):高DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止內(nèi)存到內(nèi)存的傳輸DMA_Init(DMA1_Channel1, &DMA_InitStructure); //配置DMA1DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);//使能傳輸完成中斷 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);DMA_Cmd(DMA1_Channel1,ENABLE);} //中斷處理函數(shù)void DMA1_Channel1_IRQHandler(void){int sum=0;if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET){//中斷處理代碼for(int i=0;i<10;i++){sum += ch1Value[i];}//均值濾波PWM1value = (int)map(sum/10,0,4092,1000,2000);sum=0;printf("%d\",PWM1value);printf("當(dāng)前時(shí)間:%d:%d:%d\\",calendar.hour,calendar.min,calendar.sec);TIM_SetCompare2(TIM3,PWM1value);//輸出給PWMDMA_ClearITPendingBit(DMA1_IT_TC1);//清除標(biāo)志}}//GPIO配置,PA0void GPIOA_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA時(shí)鐘 //PA6 作為模擬通道輸入引腳 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure); } //初始化ADC//這里我們僅以規(guī)則通道為例//我們默認(rèn)將開啟通道0~3 void Adc_Init(void){ ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1通道時(shí)鐘 //ADC1初始化ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //獨(dú)立ADC模式ADC_InitStructure.ADC_ScanConvMode = DISABLE; //關(guān)閉掃描方式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//關(guān)閉連續(xù)轉(zhuǎn)換模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; //使用外部觸發(fā)模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集數(shù)據(jù)右對(duì)齊ADC_InitStructure.ADC_NbrOfChannel = 1; //要轉(zhuǎn)換的通道數(shù)目ADC_Init(ADC1, &ADC_InitStructure);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC時(shí)鐘,為PCLK2的6分頻,即12MHzADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);//配置ADC1通道0為239.5個(gè)采樣周期 //使能ADC、DMAADC_DMACmd(ADC1,ENABLE);ADC_Cmd(ADC1,ENABLE); ADC_ResetCalibration(ADC1);//復(fù)位校準(zhǔn)寄存器while(ADC_GetResetCalibrationStatus(ADC1));//等待校準(zhǔn)寄存器復(fù)位完成 ADC_StartCalibration(ADC1);//ADC校準(zhǔn)while(ADC_GetCalibrationStatus(ADC1));//等待校準(zhǔn)完成ADC_ExternalTrigConvCmd(ADC1, ENABLE);//設(shè)置外部觸發(fā)模式使能} //獲得ADC值//ch:通道值 0~9u16 Get_Adc(u8 ch) { //設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );//ADC1,ADC通道,采樣時(shí)間為239.5個(gè)周期ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉(zhuǎn)換結(jié)束return ADC_GetConversionValue(ADC1);//返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果} //ch:通道值 0~9,采樣times次后作均值濾波u16 Get_Adc_Average(u8 ch,u8 times){u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=Get_Adc(ch);delay_ms(5);}return temp_val/times;}//TIM3 PWM部分初始化 //PWM輸出初始化//arr:自動(dòng)重裝值//psc:時(shí)鐘預(yù)分頻數(shù)void TIM3_PWM_Init(u16 arr,u16 psc){ GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定時(shí)器3時(shí)鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設(shè)和AFIO復(fù)用功能模塊時(shí)鐘GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5 //設(shè)置該引腳為復(fù)用輸出功能,輸出TIM3 CH2的PWM脈沖波形GPIOB.5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB //初始化TIM3TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位//初始化TIM3 Channel2 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式1,計(jì)數(shù)值<自動(dòng)重裝載值時(shí),輸出高電平 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據(jù)T指定的參數(shù)初始化外設(shè)TIM3 OC2 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預(yù)裝載寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIM3} /*函數(shù)說明:仿Arduino,將一個(gè)數(shù)字從一個(gè)范圍重新映射到另一個(gè)范圍也就是說,fromLow的值將映射到toLow,fromlhigh到toHigh的值等等。*/float map(float value,float fromLow,float fromHigh,float toLow,float toHigh){return ((value-fromLow)*(toHigh-toLow)/(fromHigh-fromLow)+toLow);}
config.h-包含函數(shù)預(yù)定義和全局變量預(yù)定義
#ifndef __CONFIG_H#define __CONFIG_H#include "stm32f10x.h" //記得添加此頭文件,因?yàn)閏onfig.c用到GPIO相關(guān)函數(shù)等#include "sys.h"extern volatile u16 ch1Value[10];//ADC采樣值extern volatile u16 PWM1value;//控制PWM占空比void TIM2_Init(u16 arr,u16 psc);//TIM2定時(shí)器初始化void TIM3_PWM_Init(u16 arr,u16 psc);//PB5定時(shí)器初始化void DMA1_Init(void);void GPIOA_Init(void);void Adc_Init(void);//ADC1初始化u16 Get_Adc(u8 ch); //獲取一次ADC的值u16 Get_Adc_Average(u8 ch,u8 times);//ADC采樣值進(jìn)行均值濾波float map(float value,float fromLow,float fromHigh,float toLow,float toHigh);//映射函數(shù)#endif
oled.c-包含各種顯示函數(shù)和IIC初始化
// // 功能描述 : 0.69寸OLED 接口演示例程(STM32F103C8T6 IIC)// 說明: // ----------------------------------------------------------------// GND 電源地// VCC 接3.3v電源// SCL 接PB8(SCL)// SDA 接PB9(SDA) //? #include "oled.h"#include "stdlib.h"#include "oledfont.h" #include "delay.h"//OLED的顯存//存放格式如下.//[0]0 1 2 3 ... 127//[1]0 1 2 3 ... 127//[2]0 1 2 3 ... 127//[3]0 1 2 3 ... 127//[4]0 1 2 3 ... 127//[5]0 1 2 3 ... 127//[6]0 1 2 3 ... 127//[7]0 1 2 3 ... 127 /**********************************************//IIC Start**********************************************/void IIC_Start(void){ OLED_SCLK_Set() ;OLED_SDIN_Set();OLED_SDIN_Clr();OLED_SCLK_Clr();} /**********************************************//IIC Stop**********************************************/void IIC_Stop(void){OLED_SCLK_Set() ;//OLED_SCLK_Clr();OLED_SDIN_Clr();OLED_SDIN_Set();} void IIC_Wait_Ack(void){OLED_SCLK_Set() ;OLED_SCLK_Clr();}/**********************************************// IIC Write byte**********************************************/ 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;//OLED_SCLK_Clr();m=m&0x80;if(m==0x80){OLED_SDIN_Set();}else OLED_SDIN_Clr();da=da<<1;OLED_SCLK_Set();OLED_SCLK_Clr();} }/**********************************************// IIC Write Command**********************************************/void Write_IIC_Command(unsigned char IIC_Command){IIC_Start();Write_IIC_Byte(0x78); //Slave address,SA0=0IIC_Wait_Ack();Write_IIC_Byte(0x00);//write commandIIC_Wait_Ack();Write_IIC_Byte(IIC_Command); IIC_Wait_Ack();IIC_Stop();}/**********************************************// IIC Write Data**********************************************/void Write_IIC_Data(unsigned char IIC_Data){ IIC_Start(); Write_IIC_Byte(0x78);//D/C#=0; R/W#=0IIC_Wait_Ack(); Write_IIC_Byte(0x40);//write dataIIC_Wait_Ack(); Write_IIC_Byte(IIC_Data);IIC_Wait_Ack(); IIC_Stop();}void OLED_WR_Byte(unsigned dat,unsigned cmd){if(cmd){Write_IIC_Data(dat);}else {Write_IIC_Command(dat);} } /********************************************// fill_Picture********************************************/void fill_picture(unsigned char fill_Data){unsigned char m,n;for(m=0;m<8;m++){OLED_WR_Byte(0xb0+m,0);//page0-page1OLED_WR_Byte(0x00,0);//low column start addressOLED_WR_Byte(0x10,0);//high column start addressfor(n=0;n<128;n++){OLED_WR_Byte(fill_Data,1);}}} //坐標(biāo)設(shè)置void OLED_Set_Pos(unsigned char x, unsigned char y) { OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f),OLED_CMD); } //開啟OLED顯示 void OLED_Display_On(void){OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD); //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON}//關(guān)閉OLED顯示 void OLED_Display_Off(void){OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF} //清屏函數(shù),清完屏,整個(gè)屏幕是黑色的!和沒點(diǎn)亮一樣!!! void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //設(shè)置頁地址(0~7)OLED_WR_Byte (0x00,OLED_CMD); //設(shè)置顯示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD); //設(shè)置顯示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新顯示}//更新顯存到OLEDu8 OLED_GRAM[128][8];void OLED_Refresh_Gram(void){u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //設(shè)置頁地址(0~7)OLED_WR_Byte (0x00,OLED_CMD); //設(shè)置顯示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD); //設(shè)置顯示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } //畫點(diǎn) //x:0~127//y:0~63//t:1 填充 0,清空 void OLED_DrawPoint(u8 x,u8 y,u8 t){u8 pos,bx,temp=0;if(x>127||y>63)return;//超出范圍了.pos=7-y/8;bx=y%8;temp=1<<(7-bx);if(t)OLED_GRAM[x][pos]|=temp;else OLED_GRAM[x][pos]&=~temp; }//x1,y1,x2,y2 填充區(qū)域的對(duì)角坐標(biāo)//確保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63 //dot:0,清空;1,填充 void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot) { u8 x,y; for(x=x1;x<=x2;x++){for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);} OLED_Refresh_Gram();//更新顯示} //在指定位置顯示一個(gè)字符,包括部分字符//x:0~127//y:0~63//mode:0,反白顯示;1,正常顯示 //size:選擇字體 12/16/24void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode){ u8 temp,t,t1;u8 y0=y;u8 csize=(size/8+((size%8)?1:0))*(size/2);//得到字體一個(gè)字符對(duì)應(yīng)點(diǎn)陣集所占的字節(jié)數(shù)chr=chr-' ';//得到偏移后的值 for(t=0;t<csize;t++) { if(size==12)temp=asc2_1206[chr][t]; //調(diào)用1206字體else if(size==16)temp=asc2_1608[chr][t];//調(diào)用1608字體else if(size==24)temp=asc2_2412[chr][t];//調(diào)用2412字體else return;//沒有的字庫 for(t1=0;t1<8;t1++){if(temp&0x80)OLED_DrawPoint(x,y,mode);else OLED_DrawPoint(x,y,!mode);temp<<=1;y++;if((y-y0)==size){y=y0;x++;break;}} } }//m^n函數(shù)u32 mypow(u8 m,u8 n){u32 result=1; while(n--)result*=m; return result;} //顯示2個(gè)數(shù)字//x,y :起點(diǎn)坐標(biāo) //len :數(shù)字的位數(shù)//size:字體大小12/16/24//mode:模式0,填充模式;1,疊加模式//num:數(shù)值(0~4294967295); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size){ u8 t,temp;u8 enshow=0; for(t=0;t<len;t++){temp=(num/mypow(10,len-t-1));if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size/2)*t,y,' ',size,1);continue;}else enshow=1; } OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); }} //顯示字符串//x,y:起點(diǎn)坐標(biāo) //size:字體大小12/16/24//*p:字符串起始地址 void OLED_ShowString(u8 x,u8 y, u8 *p,u8 size){ while((*p<='~')&&(*p>=' '))//判斷是不是非法字符! { if(x>(128-(size/2))){x=0;y+=size;} if(y>(64-size)){y=x=0;OLED_Clear();} OLED_ShowChar(x,y,*p,size,1); x+=size/2; p++; } } //顯示漢字void OLED_ShowCHinese(u8 x,u8 y,u8 no){ u8 t,adder=0;OLED_Set_Pos(x,y); for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1; }OLED_Set_Pos(x,y+1); for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1; }}/***********功能描述:顯示顯示BMP圖片128×64起始點(diǎn)坐標(biāo)(x,y),x的范圍0~127,y為頁的范圍0~7*****************/void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]){ unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1;for(y=y0;y<y1;y++){OLED_Set_Pos(x0,y); for(x=x0;x<x1;x++) { OLED_WR_Byte(BMP[j++],OLED_DATA); }}} //初始化SSD1306 void OLED_Init(void){ GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能B端口和AFIO復(fù)用功能模塊時(shí)鐘GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);//IIC1重映射 -> PB8,9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB8,9 GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9); delay_ms(800);OLED_WR_Byte(0xAE,OLED_CMD);//--顯示關(guān)閉OLED_WR_Byte(0x00,OLED_CMD);//---設(shè)置最小列地址OLED_WR_Byte(0x10,OLED_CMD);//---設(shè)置最大列地址OLED_WR_Byte(0x40,OLED_CMD);//--set start line address OLED_WR_Byte(0xB0,OLED_CMD);//--set page addressOLED_WR_Byte(0x81,OLED_CMD); // contract controlOLED_WR_Byte(0xFF,OLED_CMD);//--128 OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverseOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 dutyOLED_WR_Byte(0xC0,OLED_CMD);//Com掃描方向,若顯示的是鏡對(duì)稱,改為C8OLED_WR_Byte(0xD3,OLED_CMD);//-set display offsetOLED_WR_Byte(0x00,OLED_CMD);//OLED_WR_Byte(0xD5,OLED_CMD);//set osc divisionOLED_WR_Byte(0x80,OLED_CMD);//OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode offOLED_WR_Byte(0x05,OLED_CMD);//OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge PeriodOLED_WR_Byte(0xF1,OLED_CMD);//OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartionOLED_WR_Byte(0x12,OLED_CMD);//OLED_WR_Byte(0xDB,OLED_CMD);//set VcomhOLED_WR_Byte(0x30,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enableOLED_WR_Byte(0x14,OLED_CMD);//OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel} u8 *itoa(int num,u8 *str,int radix){char index[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//索引表unsigned unum;//存放要轉(zhuǎn)換的整數(shù)的絕對(duì)值,轉(zhuǎn)換的整數(shù)可能是負(fù)數(shù)int i=0,j,k;//i用來指示設(shè)置字符串相應(yīng)位,轉(zhuǎn)換之后i其實(shí)就是字符串的長度;轉(zhuǎn)換后順序是逆序的,有正負(fù)的情況,k用來指示調(diào)整順序的開始位置;j用來指示調(diào)整順序時(shí)的交換。 //獲取要轉(zhuǎn)換的整數(shù)的絕對(duì)值if(radix==10&&num<0)//要轉(zhuǎn)換成十進(jìn)制數(shù)并且是負(fù)數(shù){unum=(unsigned)-num;//將num的絕對(duì)值賦給unumstr[i++]='-';//在字符串最前面設(shè)置為'-'號(hào),并且索引加1}else unum=(unsigned)num;//若是num為正,直接賦值給unum //轉(zhuǎn)換部分,注意轉(zhuǎn)換后是逆序的do{str[i++]=index[unum%(unsigned)radix];//取unum的最后一位,并設(shè)置為str對(duì)應(yīng)位,指示索引加1unum/=radix;//unum去掉最后一位 }while(unum);//直至unum為0退出循環(huán) str[i]='\\0';//在字符串最后添加'\\0'字符,c語言字符串以'\\0'結(jié)束。 //將順序調(diào)整過來if(str[0]=='-') k=1;//如果是負(fù)數(shù),符號(hào)不用調(diào)整,從符號(hào)后面開始調(diào)整else k=0;//不是負(fù)數(shù),全部都要調(diào)整 u8 temp;//臨時(shí)變量,交換兩個(gè)值時(shí)用到for(j=k;j<=(i-1)/2;j++)//頭尾一一對(duì)稱交換,i其實(shí)就是字符串的長度,索引最大值比長度少1{temp=str[j];//頭部賦值給臨時(shí)變量str[j]=str[i-1+k-j];//尾部賦值給頭部str[i-1+k-j]=temp;//將臨時(shí)變量的值(其實(shí)就是之前的頭部值)賦給尾部} return str;//返回轉(zhuǎn)換后的字符串}
oled.h-包含函數(shù)預(yù)定義和OLED顯示所需的宏定義
/// 功能描述 : 0.69寸OLED 接口演示例程(STM32F103C8T6 IIC)// 說明: // ----------------------------------------------------------------// GND 電源地// VCC 接3.3v電源// SCL 接PB8(SCL)// SDA 接PB9(SDA) // ----------------------------------------------------------------//#ifndef __OLED_H#define __OLED_H #include "sys.h"#include "stdlib.h" #define OLED_MODE 0#define SIZE 8#define XLevelL0x00#define XLevelH0x10#define Max_Column128#define Max_Row64#defineBrightness0xFF #define X_width="360px",height="auto" />
其他代碼基本就是正點(diǎn)原子官方的文件了,整個(gè)工程文件已上傳天翼云盤:
https://cloud.189.cn/t/uYniA3iM3iei(訪問碼:g914)
6.實(shí)現(xiàn)效果串口調(diào)試助手查看串口輸出
OLED顯示
以上就是關(guān)于pos機(jī)操作手冊(cè)下載,STM32F103C8T6制作舵機(jī)測試儀詳細(xì)圖文教程的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于pos機(jī)操作手冊(cè)下載的知識(shí),希望能夠幫助到大家!