废话不多说,代码看着拿
#include "led.h"
void LED_Init(void)
{
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);
LED_RED_Off();
LED_R_Off();
LED_G_Off();
LED_B_Off();
}
void LED_RED_On(void) { LED_RED = 1; }
void LED_RED_Off(void) { LED_RED = 0; }
void LED_RED_Tog(void) { LED_RED ^= 1; }
void LED_R_Off(void) { LED_R = 0;}
void LED_G_Off(void) { LED_G = 0;}
void LED_B_Off(void) { LED_B = 0; }
void LED_R_On(void) { LED_R = 1; }
void LED_G_On(void) { LED_G = 1; }
void LED_B_On(void) { LED_B = 1; }
void LED_R_Tog(void) { LED_R ^= 1; }
void LED_G_Tog(void) { LED_G ^= 1; }
void LED_B_Tog(void) { LED_B ^= 1; }
//白色 White
void LED_W_On(void)
{
LED_R_On();
LED_G_On();
LED_B_On();
}
//白色 White
void LED_W_Off(void)
{
LED_R_Off();
LED_G_Off();
LED_B_Off();
}
//白色 White
void LED_W_Tog(void)
{
LED_R_Tog();
LED_G_Tog();
LED_B_Tog();
}
//黄色 Yellow
void LED_Y_On(void)
{
LED_R_On();
LED_G_On();
LED_B_Off();
}
//品红 Pinkish red
void LED_P_On(void)
{
LED_R_On();
LED_G_Off();
LED_B_On();
}
//青色 Cyan
void LED_C_On(void)
{
LED_R_Off();
LED_G_On();
LED_B_On();
}
#include "key.h"
//按键初始化函数
void KEY_Init(void) //IO初始化
{
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4);
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY1按下
//2,KEY2按下
//注意此函数有响应优先级,KEY1>KEY2!!
uint8_t KEY_Scan(uint8_t mode)
{
uint16_t i;
static uint8_t key_up = 1; //按键按松开标志
if (mode)
key_up = 1; //支持连按
if (key_up && (KEY2 == 0 || KEY1 == 0))
{
for (i = 0; i < 5000; i++)
; //去抖动
key_up = 0;
if (KEY1 == 0)
return KEY1_PRES;
else if (KEY2 == 0)
return KEY2_PRES;
}
else if (KEY2 == 1 && KEY1 == 1)
key_up = 1;
return 0; // 无按键按下
}
#include "key4x4.h"
/****************************************************/
/************ 接法如下 ************/
/*
* Rows and columns 行和列
*
* R4 R3 R2 R1 C1 C2 C3 C4
* P4.0 P4.1 P4.2 P4.3 P4.4 P4.5 P4.6 P4.7
*
* 返回的键值 : S1=16 S2=15 S3=14...... S16=1
*/
/*****************************************************/
//函数功能:延时
void key_delay(uint16_t t);
void KEY4x4_Init(void)
{
P4DIR &= ~(BIT0 | BIT1 | BIT2 | BIT3); // P4.0~3 设为输入
P4REN |= BIT0 | BIT1 | BIT2 | BIT3; // P4.0~3 使能上拉/下拉电阻
P4OUT |= BIT0 | BIT1 | BIT2 | BIT3; // P4.0~3 上拉
P4DIR |= BIT4 | BIT5 | BIT6 | BIT7; // P4.4~7 设为输出
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按; 1,支持连续按
uint8_t KEY4x4_Scan(bool mode)
{
uint8_t i;
static bool key_up = true; //按键按松开标志
if (mode)
key_up = true; //支持连按
if ((~(P4IN | 0xf0)) && key_up)
{
key_delay(25); //去抖动
for (i = 0; i < 4; i++)
{
key_up = false;
P4OUT = ~(1 << (i + 4)); //+4是应为 忽略低四位
switch (~P4IN & 0x0F) //第i+1行
{
case 0x08: //第四列
return i + 1;
case 0x04: //第三列
return i + 5;
case 0x02: //第二列
return i + 9;
case 0x01: //第一列
return i + 13;
}
}
}
else if ((P4IN & 0x01) && (P4IN & 0x02) && (P4IN & 0x04) && (P4IN & 0x08))
key_up = true;
return 0;
}
//函数功能:延时
static void key_delay(uint16_t t)
{
volatile uint16_t x;
while (t--)
for (x = 0; x < 1000; x++)
;
}
#include "exit.h"
#include "led.h"
int num=0,num1=0;
void Exit_Init(void)
{
//IO初始化
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P6, GPIO_PIN5);
//2.清除中断标志位
GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN5);
GPIO_clearInterruptFlag(GPIO_PORT_P6, GPIO_PIN5);
//3.配置触发方式
GPIO_interruptEdgeSelect(GPIO_PORT_P5, GPIO_PIN5,GPIO_HIGH_TO_LOW_TRANSITION);
GPIO_interruptEdgeSelect(GPIO_PORT_P6, GPIO_PIN5,GPIO_LOW_TO_HIGH_TRANSITION);
//4.开启外部中断
GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);
GPIO_enableInterrupt(GPIO_PORT_P6, GPIO_PIN5);
//5.开启端口中断
Interrupt_enableInterrupt(INT_PORT5);
Interrupt_enableInterrupt(INT_PORT6);
//6.开启总中断
Interrupt_enableMaster();
}
void PORT5_IRQHandler(void)
{
uint16_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P5);
GPIO_clearInterruptFlag(GPIO_PORT_P5,status);
if(BITBAND_PERI(P5IN, 5)==0)
{
******
}
}
void PORT6_IRQHandler(void)
{
uint16_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P6);
GPIO_clearInterruptFlag(GPIO_PORT_P6,status);
if(BITBAND_PERI(P6IN, 5)==1)
{
******
}
}
#include "usart.h"
#include "baudrate_calculate.h"
//预编译
//if 1 使用标准C库 如果报错就使用微库
//if 0 使用微库 得去勾选魔术棒里的 Use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
#else
int fgetc(FILE *f)
{
while (EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG !=
UART_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG))
;
return UART_receiveData(EUSCI_A0_BASE);
}
#endif
int fputc(int ch, FILE *f)
{
UART_transmitData(EUSCI_A0_BASE, ch & 0xFF);
return ch;
}
void UARTA0_Init(void)
{
//1.配置GPIO复用
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
//2.配置UART结构体
#ifdef EUSCI_A_UART_7_BIT_LEN
//固件库v3_40_01_02
//默认SMCLK 48MHz 比特率 115200
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
26, // BRDIV = 26
0, // UCxBRF = 0
111, // UCxBRS = 111
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // MSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, 115200); //配置波特率
#else
//固件库v3_21_00_05
//默认SMCLK 48MHz 比特率 115200
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
26, // BRDIV = 26
0, // UCxBRF = 0
111, // UCxBRS = 111
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // MSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
};
eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, 115200); //配置波特率
#endif
//3.初始化串口
UART_initModule(EUSCI_A0_BASE, &uartConfig);
//4.开启串口模块
UART_enableModule(EUSCI_A0_BASE);
//5.开启串口相关中断
UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
//6.开启串口端口中断
Interrupt_enableInterrupt(INT_EUSCIA0);
//7.开启总中断
Interrupt_enableMaster();
}
#include "timA.h"
/************************************** TIMA0 *******************************************/
void TimA0_Int_Init(uint16_t ccr0, uint16_t psc)
{
// 1.增计数模式初始化
Timer_A_UpModeConfig upConfig;
upConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源
upConfig.clockSourceDivider = psc; //时钟分频 范围1-64
upConfig.timerPeriod = ccr0; //自动重装载值(ARR)
upConfig.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; //禁用 tim溢出中断
upConfig.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE; //启用 ccr0更新中断
upConfig.timerClear = TIMER_A_DO_CLEAR; // Clear value
// 2.初始化定时器A
MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upConfig);
// 3.选择模式开始计数
MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
// 4.清除比较中断标志位
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
// 5.开启串口端口中断
MAP_Interrupt_enableInterrupt(INT_TA0_0);
}
// 6.编写TIMA ISR
void TA0_0_IRQHandler(void)
{
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);
/*开始填充用户代码*/
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
/*结束填充用户代码*/
}
#include "pwm.h"
void TimA0_PWM_Init(uint16_t ccr0, uint16_t psc)
{
/*初始化引脚*/
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION);
// MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
Timer_A_PWMConfig TimA0_PWMConfig;
/*定时器PWM初始化*/
TimA0_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源
TimA0_PWMConfig.clockSourceDivider = psc; //时钟分频 范围1-64
TimA0_PWMConfig.timerPeriod = ccr0; //自动重装载值(ARR)
TimA0_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; //通道一
TimA0_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET; //输出模式
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TimA0_PWMConfig); /* 初始化比较寄存器以产生 PWM1 */
TimA0_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2; //通道2
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TimA0_PWMConfig);
}
#include "sg90.h"
#include "delay.h"
/*
20ms为例
0.5ms ------------ 0度;
1.0ms ------------ 45度;
1.5ms ------------ 90度;
2.0ms ------------ 135度;
2.5ms ------------ 180度;
*/
void SG90_angle(int a)
{
int pwm=500+2000/180*a;
MAP_Timer_A_setCompareValue(TIMER_A2_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, pwm);
}
void SG90_Cal(void)
{
int i=0,j=0;
for(i=0;i<=180;i++)
{
delay_ms(65);
SG90_angle(i);
}
for(j=180;j>=0;j--)
{
delay_ms(65);
SG90_angle(j);
}
}
/*********************
*
* 最大采集电压 3.3V
*
* ADC采集引脚:
* 单路 为 P5.5
* 双路 为 P5.5 P5.4
* 三路 为 P5.5 P5.4 P5.3
*
************************/
#include "adc.h"
#include "usart.h"
//总时间 M*N*21us
#define N 200 //采样次数
#define M 3 //采样通道个数
static uint16_t resultsBuffer[M];
void ADC_Config(void)
{
/* 启用浮点运算的FPU */
MAP_FPU_enableModule();
MAP_FPU_enableLazyStacking();
/* Initializing ADC (MCLK/1/1) */
MAP_ADC14_enableModule(); //使能ADC14模块
MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_4, ADC_DIVIDER_5, ADC_NOROUTE); //初始化ADC 时钟 分频 通道 2.4MHz
#if M == 1
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION); //模拟输入
MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true); //单通道配置 多次转化true
MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A0, false); //使用内部电源电压参考 非差分输入false
MAP_ADC14_enableInterrupt(ADC_INT0); //ADC通道0的中断
#elif M == 2
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5 | GPIO_PIN4, GPIO_TERTIARY_MODULE_FUNCTION);
MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM1, true); //多通道配置 多次转化true
MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A0, false);
MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A1, false);
MAP_ADC14_enableInterrupt(ADC_INT1);
#elif M == 3
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN3, GPIO_TERTIARY_MODULE_FUNCTION); //
MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM2, true);
MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A0, false);
MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A1, false);
MAP_ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A2, false);
MAP_ADC14_enableInterrupt(ADC_INT2);
#endif
/* Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_ADC14); //ADC模块的中断
MAP_Interrupt_enableMaster();
/* Setting up the sample timer to automatically step through the sequence
* convert.
*/
MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION); //自动触发
/* Triggering the start of the sample */
MAP_ADC14_enableConversion(); //使能开始转换(触发后 自动ADC上电)
MAP_ADC14_toggleConversionTrigger(); //开启第一次软件触发
}
void ADC14_IRQHandler(void)
{
uint8_t i = 0;
uint_fast64_t status = MAP_ADC14_getEnabledInterruptStatus();
MAP_ADC14_clearInterruptFlag(status);
#if M == 1
if (ADC_INT0 & status)
#elif M == 2
if (ADC_INT1 & status)
#elif M == 3
if (ADC_INT2 & status)
#endif
{
MAP_ADC14_getMultiSequenceResult(resultsBuffer);
for (i = 0; i < M; i++)
{
float temp=resultsBuffer[i]*(3.3/16383);
printf("ADC14_CH[%d]:%d ----- %f\r\n", i, resultsBuffer[i],temp);
}
printf("\r\n");
}
}
#include "oled.h"
#include "oledfont.h"
#include "delay.h"
#define OLED_DATA 1
#define OLED_CMD 0
//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
#if (TRANSFER_METHOD == HW_IIC)
//I2C_Configuration,初始化硬件IIC引脚
void I2C_Configuration(void)
{
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(
IIC_GPIOX, IIC_SCL_Pin | IIC_SDA_Pin, GPIO_PRIMARY_MODULE_FUNCTION);
const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
48000000, // SMCLK = 48MHz
EUSCI_B_I2C_SET_DATA_RATE_1MBPS, // Desired I2C Clock of 1MHz(实际可以更高,根据I2C协议可以3.4MHz,注意上拉电阻配置
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
MAP_I2C_initMaster(EUSCI_BX, &i2cConfig);
MAP_I2C_setSlaveAddress(EUSCI_BX, OLED_ADDRESS);
MAP_I2C_setMode(EUSCI_BX, EUSCI_B_I2C_TRANSMIT_MODE);
MAP_I2C_enableModule(EUSCI_BX);
// MAP_I2C_clearInterruptFlag(
// EUSCI_BX, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 | EUSCI_B_I2C_NAK_INTERRUPT);
// MAP_I2C_enableInterrupt(
// EUSCI_BX, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 | EUSCI_B_I2C_NAK_INTERRUPT);
// MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
}
//发送一个字节
//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(uint8_t dat, uint8_t mode)
{
if (mode)
MAP_I2C_masterSendMultiByteStart(EUSCI_BX, 0x40);
else
MAP_I2C_masterSendMultiByteStart(EUSCI_BX, 0x00);
MAP_I2C_masterSendMultiByteFinish(EUSCI_BX, dat);
}
#elif (TRANSFER_METHOD == SW_IIC)
void I2C_SW_Configuration()
{
OLED_SSD1306_SCL_IO_INIT;
OLED_SSD1306_SDA_IO_INIT;
delay_ms(200);
}
//起始信号
void I2C_Start(void)
{
OLED_SDA_Set();
OLED_SCL_Set();
OLED_SDA_Clr();
OLED_SCL_Clr();
}
//结束信号
void I2C_Stop(void)
{
OLED_SDA_Clr();
OLED_SCL_Set();
OLED_SDA_Set();
}
//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{
OLED_SDA_Set();
OLED_SCL_Set();
OLED_SCL_Clr();
}
//写入一个字节
void Send_Byte(uint8_t dat)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
OLED_SCL_Clr(); //将时钟信号设置为低电平
if (dat & 0x80) //将dat的8位从最高位依次写入
{
OLED_SDA_Set();
}
else
{
OLED_SDA_Clr();
}
OLED_SCL_Set();
OLED_SCL_Clr();
dat <<= 1;
}
}
//发送一个字节
//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(uint8_t dat, uint8_t mode)
{
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
if (mode)
{
Send_Byte(0x40);
}
else
{
Send_Byte(0x00);
}
I2C_WaitAck();
Send_Byte(dat);
I2C_WaitAck();
I2C_Stop();
}
#elif (TRANSFER_METHOD == HW_SPI)
//暂未支持
#endif
//反显函数
void OLED_ColorTurn(uint8_t i)
{
if (i == 0)
{
OLED_WR_Byte(0xA6, OLED_CMD); //正常显示
}
if (i == 1)
{
OLED_WR_Byte(0xA7, OLED_CMD); //反色显示
}
}
//屏幕旋转180度
void OLED_DisplayTurn(uint8_t i)
{
if (i == 0)
{
OLED_WR_Byte(0xC8, OLED_CMD); //正常显示
OLED_WR_Byte(0xA1, OLED_CMD);
}
if (i == 1)
{
OLED_WR_Byte(0xC0, OLED_CMD); //反转显示
OLED_WR_Byte(0xA0, OLED_CMD);
}
}
//坐标设置
void OLED_Set_Pos(uint8_t x, uint8_t 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 ON
OLED_WR_Byte(0XAF, OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D, OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10, OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE, OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
uint8_t i, n;
for (i = 0; i < 8; i++)
{
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置―列低地址
OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置―列高地址
for (n = 0; n < 128; n++)
OLED_WR_Byte(0, OLED_DATA);
} //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//sizey:选择字体 6x8 8x16
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t sizey)
{
uint8_t c = 0, sizex = sizey / 2;
uint16_t i = 0, size1;
if (sizey == 8)
size1 = 6;
else
size1 = (sizey / 8 + ((sizey % 8) ? 1 : 0)) * (sizey / 2);
c = chr - ' '; //得到偏移后的值
OLED_Set_Pos(x, y);
for (i = 0; i < size1; i++)
{
if (i % sizex == 0 && sizey != 8)
OLED_Set_Pos(x, y++);
if (sizey == 8)
OLED_WR_Byte(asc2_0806[c][i], OLED_DATA); //6X8字号
else if (sizey == 16)
OLED_WR_Byte(asc2_1608[c][i], OLED_DATA); //8x16字号
// else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号
else
return;
}
}
//m^n函数
uint32_t oled_pow(uint8_t m, uint8_t n)
{
uint32_t result = 1;
while (n--)
result *= m;
return result;
}
//显示数字
//x,y :起点坐标
//num:要显示的数字
//len :数字的位数
//sizey:字体大小
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t sizey)
{
uint8_t t, temp, m = 0;
uint8_t enshow = 0;
if (sizey == 8)
m = 2;
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 + (sizey / 2 + m) * t, y, ' ', sizey);
continue;
}
else
enshow = 1;
}
OLED_ShowChar(x + (sizey / 2 + m) * t, y, temp + '0', sizey);
}
}
//显示一个字符号串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t sizey)
{
uint8_t j = 0;
while (chr[j] != '\0')
{
OLED_ShowChar(x, y, chr[j++], sizey);
if (sizey == 8)
x += 6;
else
x += sizey / 2;
}
}
//显示汉字
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t no, uint8_t sizey)
{
uint16_t i, size1 = (sizey / 8 + ((sizey % 8) ? 1 : 0)) * sizey;
for (i = 0; i < size1; i++)
{
if (i % sizey == 0)
OLED_Set_Pos(x, y++);
if (sizey == 16)
OLED_WR_Byte(Hzk[no][i], OLED_DATA); //16x16字号
// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号
else
return;
}
}
//显示图片
//x,y显示坐标
//sizex,sizey,图片长宽
//BMP:要显示的图片
void OLED_DrawBMP(uint8_t x, uint8_t y, uint8_t sizex, uint8_t sizey, uint8_t BMP[])
{
uint16_t j = 0;
uint8_t i, m;
sizey = sizey / 8 + ((sizey % 8) ? 1 : 0);
for (i = 0; i < sizey; i++)
{
OLED_Set_Pos(x, i + y);
for (m = 0; m < sizex; m++)
{
OLED_WR_Byte(BMP[j++], OLED_DATA);
}
}
}
//初始化SSD1306
void OLED_Init(void)
{
#if (TRANSFER_METHOD == HW_IIC)
I2C_Configuration();
#elif (TRANSFER_METHOD == SW_IIC)
I2C_SW_Configuration();
#elif (TRANSFER_METHOD == HW_SPI)
SPI_Configuration();
#endif
OLED_WR_Byte(0xAE, OLED_CMD); //--turn off oled panel
OLED_WR_Byte(0x00, OLED_CMD); //---set low column address
OLED_WR_Byte(0x10, OLED_CMD); //---set high column address
OLED_WR_Byte(0x40, OLED_CMD); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81, OLED_CMD); //--set contrast control register
OLED_WR_Byte(0xCF, OLED_CMD); // Set SEG Output Current Brightness
OLED_WR_Byte(0xA1, OLED_CMD); //--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8, OLED_CMD); //Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6, OLED_CMD); //--set normal display
OLED_WR_Byte(0xA8, OLED_CMD); //--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f, OLED_CMD); //--1/64 duty
OLED_WR_Byte(0xD3, OLED_CMD); //-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00, OLED_CMD); //-not offset
OLED_WR_Byte(0xd5, OLED_CMD); //--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80, OLED_CMD); //--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9, OLED_CMD); //--set pre-charge period
OLED_WR_Byte(0xF1, OLED_CMD); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA, OLED_CMD); //--set com pins hardware configuration
OLED_WR_Byte(0x12, OLED_CMD);
OLED_WR_Byte(0xDB, OLED_CMD); //--set vcomh
OLED_WR_Byte(0x40, OLED_CMD); //Set VCOM Deselect Level
OLED_WR_Byte(0x20, OLED_CMD); //-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02, OLED_CMD); //
OLED_WR_Byte(0x8D, OLED_CMD); //--set Charge Pump enable/disable
OLED_WR_Byte(0x14, OLED_CMD); //--set(0x10) disable
OLED_WR_Byte(0xA4, OLED_CMD); // Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6, OLED_CMD); // Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte(0xAF, OLED_CMD); /*display ON*/
}
#include "vofa.h"
#include "usart.h"
void Float_to_Byte(float f,unsigned char byte[])
{
FloatLongType fl;
fl.fdata=f;
byte[0]=(unsigned char)fl.ldata;
byte[1]=(unsigned char)(fl.ldata>>8);
byte[2]=(unsigned char)(fl.ldata>>16);
byte[3]=(unsigned char)(fl.ldata>>24);
}
void SendDatatoVoFA(u8 byte[],float v_real)//缓冲数组,实际值
{
u8 t_test=0;//四位发送
u8 send_date[4]={0};//发送数据
//发送数据,绘制图像
Float_to_Byte(v_real,byte);//当前速度
// Float_to_Byte(num*1.0,byte);
for(t_test=0;t_test<4;t_test++)
{
UART_transmitData(EUSCI_A0_BASE, byte[t_test]);
}
send_date[0]=0X00;send_date[1]=0X00;
send_date[2]=0X80;send_date[3]=0X7f;
for(t_test=0;t_test<4;t_test++)
{
UART_transmitData(EUSCI_A0_BASE, send_date[t_test]);
}
}
#include "motor.h"
/*************************************************
* 函 数 名:gpio_init
* 功 能:初始化gpio口
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* MODE:输入输出模式选择,在exingpio.h文件枚举
* out_value:当设置成输出时,此位设置输出电平1:高电平 0:低电平
* 当设置成输入时,此位设置上下拉电阻 1:上拉 0:下拉
* 注意事项:无
*************************************************/
void gpio_init(uint_fast8_t selectedPort,uint_fast16_t selectedPins,int MODE,unsigned int out_value)
{
switch(MODE)
{
case 0:
gpio_set_Asout(selectedPort,selectedPins);
gpio_disable_Ren(selectedPort,selectedPins);
if(out_value)
gpio_set_High(selectedPort,selectedPins);
else
gpio_set_Low(selectedPort,selectedPins);
break;
case 1:
gpio_set_Asin(selectedPort,selectedPins);
gpio_enable_Ren(selectedPort,selectedPins);
if(out_value)
gpio_set_High(selectedPort,selectedPins);
else
gpio_set_Low(selectedPort,selectedPins);
break;
}
}
/*************************************************
* 函 数 名:gpio_set_Asout
* 功 能:将GPIO引脚设置为输出
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:无
*************************************************/
void gpio_set_Asout(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->DIR |= selectedPins; break;
case(GPIO_PORT_P2):P2->DIR |= selectedPins; break;
case(GPIO_PORT_P3):P3->DIR |= selectedPins; break;
case(GPIO_PORT_P4):P4->DIR |= selectedPins; break;
case(GPIO_PORT_P5):P5->DIR |= selectedPins; break;
case(GPIO_PORT_P6):P6->DIR |= selectedPins; break;
case(GPIO_PORT_P7):P7->DIR |= selectedPins; break;
case(GPIO_PORT_P8):P8->DIR |= selectedPins; break;
case(GPIO_PORT_P9):P9->DIR |= selectedPins; break;
case(GPIO_PORT_P10):P10->DIR |= selectedPins; break;
default:;
}
}
/*************************************************
* 函 数 名:gpio_disable_Ren
* 功 能:将GPIO引脚上下拉电阻禁能
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:无
*************************************************/
void gpio_disable_Ren(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->REN &= ~selectedPins; break;
case(GPIO_PORT_P2):P2->REN &= ~selectedPins; break;
case(GPIO_PORT_P3):P3->REN &= ~selectedPins; break;
case(GPIO_PORT_P4):P4->REN &= ~selectedPins; break;
case(GPIO_PORT_P5):P5->REN &= ~selectedPins; break;
case(GPIO_PORT_P6):P6->REN &= ~selectedPins; break;
case(GPIO_PORT_P7):P7->REN &= ~selectedPins; break;
case(GPIO_PORT_P8):P8->REN &= ~selectedPins; break;
case(GPIO_PORT_P9):P9->REN &= ~selectedPins; break;
case(GPIO_PORT_P10):P10->REN &= ~selectedPins; break;
default:;
}
}
/*************************************************
* 函 数 名:gpio_set_High
* 功 能:将GPIO引脚设置为高电平
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:当上下拉电阻使能时,该函数可设置使用上拉电阻
*************************************************/
void gpio_set_High(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->OUT |= selectedPins; break;
case(GPIO_PORT_P2):P2->OUT |= selectedPins; break;
case(GPIO_PORT_P3):P3->OUT |= selectedPins; break;
case(GPIO_PORT_P4):P4->OUT |= selectedPins; break;
case(GPIO_PORT_P5):P5->OUT |= selectedPins; break;
case(GPIO_PORT_P6):P6->OUT |= selectedPins; break;
case(GPIO_PORT_P7):P7->OUT |= selectedPins; break;
case(GPIO_PORT_P8):P8->OUT |= selectedPins; break;
case(GPIO_PORT_P9):P9->OUT |= selectedPins; break;
case(GPIO_PORT_P10):P10->OUT |= selectedPins; break;
default:;
}
}
/*************************************************
* 函 数 名:gpio_set_Low
* 功 能:将GPIO引脚设置为高电平
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:当上下拉电阻使能时,该函数可设置使用下拉电阻
*************************************************/
void gpio_set_Low(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->OUT &= ~selectedPins; break;
case(GPIO_PORT_P2):P2->OUT &= ~selectedPins; break;
case(GPIO_PORT_P3):P3->OUT &= ~selectedPins; break;
case(GPIO_PORT_P4):P4->OUT &= ~selectedPins; break;
case(GPIO_PORT_P5):P5->OUT &= ~selectedPins; break;
case(GPIO_PORT_P6):P6->OUT &= ~selectedPins; break;
case(GPIO_PORT_P7):P7->OUT &= ~selectedPins; break;
case(GPIO_PORT_P8):P8->OUT &= ~selectedPins; break;
case(GPIO_PORT_P9):P9->OUT &= ~selectedPins; break;
case(GPIO_PORT_P10):P10->OUT &= ~selectedPins; break;
default:;
}
}
/*************************************************
* 函 数 名:gpio_enable_Ren
* 功 能:将GPIO引脚上下拉电阻使能
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:无
*************************************************/
void gpio_enable_Ren(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->REN |= selectedPins; break;
case(GPIO_PORT_P2):P2->REN |= selectedPins; break;
case(GPIO_PORT_P3):P3->REN |= selectedPins; break;
case(GPIO_PORT_P4):P4->REN |= selectedPins; break;
case(GPIO_PORT_P5):P5->REN |= selectedPins; break;
case(GPIO_PORT_P6):P6->REN |= selectedPins; break;
case(GPIO_PORT_P7):P7->REN |= selectedPins; break;
case(GPIO_PORT_P8):P8->REN |= selectedPins; break;
case(GPIO_PORT_P9):P9->REN |= selectedPins; break;
case(GPIO_PORT_P10):P10->REN |= selectedPins; break;
default:;
}
}
/*************************************************
* 函 数 名:gpio_set_Asin
* 功 能:将GPIO引脚设置为输入
* 参 数:selectedPort:端口号
* selectedPins:引脚号
* 注意事项:无
*************************************************/
void gpio_set_Asin(uint_fast8_t selectedPort,uint_fast16_t selectedPins)
{
switch(selectedPort)
{
case(GPIO_PORT_P1):P1->DIR &= ~selectedPins; break;
case(GPIO_PORT_P2):P2->DIR &= ~selectedPins; break;
case(GPIO_PORT_P3):P3->DIR &= ~selectedPins; break;
case(GPIO_PORT_P4):P4->DIR &= ~selectedPins; break;
case(GPIO_PORT_P5):P5->DIR &= ~selectedPins; break;
case(GPIO_PORT_P6):P6->DIR &= ~selectedPins; break;
case(GPIO_PORT_P7):P7->DIR &= ~selectedPins; break;
case(GPIO_PORT_P8):P8->DIR &= ~selectedPins; break;
case(GPIO_PORT_P9):P9->DIR &= ~selectedPins; break;
case(GPIO_PORT_P10):P10->DIR &= ~selectedPins; break;
default:;
}
}
#include "tim32.h"
#include "usart.h"
void Tim32_0_Int_Init(uint32_t aar, uint8_t psc)
{
MAP_Timer32_initModule(TIMER32_0_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);
MAP_Timer32_setCount(TIMER32_0_BASE, aar);
MAP_Timer32_enableInterrupt(TIMER32_0_BASE);
MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 false
MAP_Interrupt_enableInterrupt(INT_T32_INT1);
}
/* Timer32 ISR */
void T32_INT1_IRQHandler(void)
{
MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);
/*开始填充用户代码*/
static uint8_t timer_second = 0;
//一般在频率较高的中断不常用 这个printf比较费时间 这里只是演示
printf("\r\nTim32_0: %ds Timeout\r\n", ++timer_second);
/*结束填充用户代码*/
}
void Tim32_1_Int_Init(uint32_t aar, uint8_t psc)
{
MAP_Timer32_initModule(TIMER32_1_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);
MAP_Timer32_setCount(TIMER32_1_BASE, aar);
MAP_Timer32_enableInterrupt(TIMER32_1_BASE);
MAP_Timer32_startTimer(TIMER32_1_BASE, false); //连续计数模式 false
MAP_Interrupt_enableInterrupt(INT_T32_INT2);
}
/* Timer32 ISR */
void T32_INT2_IRQHandler(void)
{
MAP_Timer32_clearInterruptFlag(TIMER32_1_BASE);
int i=1;
/*开始填充用户代码*/
printf("\r\n\r\nTim32_1: %ds Timeout\r\n\r\n", 16*i++);
/*结束填充用户代码*/
}
#include"PID.h"
#include"math.h"
//初始化PID结构体参数
void PID_Init(PID * s_PID,PID_VAR_TYPE set_point,PID_VAR_TYPE Proportion,PID_VAR_TYPE Integral, PID_VAR_TYPE Derivative)
{
s_PID->SetPoint = set_point;
s_PID->Proportion = Proportion;
s_PID->Integral = Integral;
s_PID->Derivative = Derivative;
s_PID->Error = 0;
s_PID->LastError = 0;
s_PID->PrevError = 0;
s_PID->SumError = 0;
s_PID->LastResult = 0;
s_PID->Result = 0;
s_PID->OutMax = DEFAULT_PID_OUT_MAX;
s_PID->OutMin = DEFAULT_PID_OUT_MIN;
s_PID->IntegralMax = DEFAULT_PID_INTEGRAL_OUT_MAX;
s_PID->IntegralMin = DEFAULT_PID_INTEGRAL_OUT_MIN;
}
//设置目标值
void PID_SetPoint (PID * s_PID, PID_VAR_TYPE set_point)
{
s_PID->SetPoint = set_point;
}
//设置PID输出范围
void PID_SetOutRange (PID * s_PID, PID_VAR_TYPE outMax,PID_VAR_TYPE outMin)
{
s_PID->OutMax = outMax;
s_PID->OutMin = outMin;
}
//设置PID积分范围
void PID_SetIntegralOutRange(PID * s_PID, PID_VAR_TYPE outMax,PID_VAR_TYPE outMin)
{
s_PID->IntegralMax = outMax;
s_PID->IntegralMin = outMin;
}
//增量式PID计算
PID_VAR_TYPE Increment_PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{
s_PID->LastResult = s_PID->Result; // 简单赋值运算
//误差计算
s_PID->Error = s_PID->SetPoint - now_point;
//PID计算
s_PID->Result = s_PID->LastResult
+ s_PID->Proportion * (s_PID->Error - s_PID->LastError) // 比例项
+ s_PID->Integral * s_PID->Error // 积分项
+ s_PID->Derivative * (s_PID->Error - 2*(s_PID->LastError) + s_PID->PrevError); // 微分项
s_PID->PrevError = s_PID->LastError; // 简单赋值运算
s_PID->LastError = s_PID->Error; // 简单赋值运算
//输出限幅
if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;
else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;
return s_PID->Result;
}
//位置式PID计算
PID_VAR_TYPE Position_PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{
s_PID->LastResult = s_PID->Result; // 简单赋值运算
//误差计算
s_PID->Error = s_PID->SetPoint - now_point;
s_PID->SumError += s_PID->Error; //积分误差累加
//积分限幅
PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;
if(IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;
else if(IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;
//PID计算
s_PID->Result = s_PID->Proportion * s_PID->Error // 比例项
+ IOutValue // 积分项
+ s_PID->Derivative * (s_PID->Error - s_PID->LastError); // 微分项
s_PID->PrevError = s_PID->LastError; // 简单赋值运算
s_PID->LastError = s_PID->Error; // 简单赋值运算
//输出限幅
if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;
else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;
return s_PID->Result;
}
//比例外置式PID
PID_VAR_TYPE PID_Cal(PID * s_PID,PID_VAR_TYPE now_point)
{
s_PID->LastResult = s_PID->Result; // 简单赋值运算
//误差计算
s_PID->Error = s_PID->SetPoint - now_point;
s_PID->SumError += s_PID->Error; //积分误差累加
//积分限幅
PID_VAR_TYPE IOutValue = s_PID->SumError * s_PID->Integral;
if(IOutValue > s_PID->IntegralMax)IOutValue = s_PID->IntegralMax;
else if(IOutValue < s_PID->IntegralMin)IOutValue = s_PID->IntegralMin;
//PID计算
s_PID->Result = s_PID->Proportion *
(s_PID->Error + IOutValue + s_PID->Derivative * (s_PID->Error - s_PID->LastError) );
s_PID->PrevError = s_PID->LastError; // 简单赋值运算
s_PID->LastError = s_PID->Error; // 简单赋值运算
//输出限幅
if(s_PID->Result > s_PID->OutMax)s_PID->Result = s_PID->OutMax;
else if(s_PID->Result < s_PID->OutMin)s_PID->Result = s_PID->OutMin;
return s_PID->Result;
}
全部工程代码联系下方wx即可
可提供一定的技术支持