ARM DIY进程18:RC5红外遥控解码
使用EITX外部中断结合定时器2中断实现了RC5格式红外遥控解码,RC5格式编码方式主要应用在SAA3010,HS3010等红外遥控芯片上,其编码格式与upd6121等有所不同,见图1.
图1
详细技术资料可参阅ST官方《应用笔记AN3174》。进程使用了GPIOA.1做红外信号输入口见图2,开发板上U8温度传感器的接口刚好可以利用,只是红外接收模块有2引脚要对调一下。主要代码移植自ST官方RC5解码应用实例,对其中关键代码进行了修改。刚好家中马兰士AV功放的遥控器采用了RC5编码,可以用来进行测试了,见图3。
图2
图3
解码后的2位数字的遥控编码值直接在LCD上显示,同时通过USART1将解码结果在PC机的超级终端上显示,见图4.
图4
主要代码:
//RC5_IR_Emul_Receiver.h
#ifndef __RC5_IR_EMUL_RECEIVER_H
#define __RC5_IR_EMUL_RECEIVER_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum { NO = 0, YES = !NO} StatusYesOrNo;
/* RC5 frame structure*/
typedef struct
{
__IO uint8_t ToggleBit; /* Toggle bit field */
__IO uint8_t Address; /* Address field */
__IO uint8_t Command; /* Command field */
} RC5Frame_TypeDef;
/* Exported constants --------------------------------------------------------*/
#define RC5_GPIO_PORT GPIOA /* Port which RC5 is connected */
#define RC5_GPIO_CLK RCC_APB2Periph_GPIOA /* Clock of Port which RC5 is connected */
#define RC5_GPIO_PIN GPIO_Pin_1 /* Pin which RC5 is connected */
#define RC5_EXTI_PORT_SOURCE GPIO_PortSourceGPIOA /* RC5 EXTI Port source */
#define RC5_EXTI_PIN_SOURCE GPIO_PinSource1 /* RC5 EXTI Pin source */
#define RC5_EXTI_IRQn EXTI1_IRQn /* RC5 EXTI IRQ */
#define RC5_EXTI_LINE EXTI_Line1 /* RC5 EXTI line */
#define RC5_EXTI_IRQHandler EXTI1_IRQHandler /* RC5 IRQ handler */
#define RC5_TIM TIM2 /* Timer used for RC5 decoding */
#define RC5_TIM_CLK RCC_APB1Periph_TIM2 /* Clock of the used timer */
#define RC5_TIM_IRQn TIM2_IRQn /* RC5 TIM IRQ */
#define RC5_TIM_IRQHandler TIM2_IRQHandler /* RC5 TIM IRQ handler */
void RC5_Receiver_Init(void);
void RC5_Sample_Data(void);
void RC5_MeasureFirstLowDuration(void);
RC5Frame_TypeDef RC5_Decode(void);
#ifdef __cplusplus
}
#endif
#endif
//RC5_IR_Emul_Receiver.C
#include "stm32f10x.h"
#include "RC5_IR_Emul_Receiver.h"
typedef enum { NOTOK = 0, OK = !NOTOK} BitTimigStatus;
#define NOMINAL_HALF_BIT_TIME_US 889
#define MIN_HALF_BIT_TIME_US 640
#define MAX_HALF_BIT_TIME_US 1140
#define NOMINAL_FULL_BIT_TIME_US 1778
#define MIN_FULL_BIT_TIME_US 1340
#define MAX_FULL_BIT_TIME_US 2220
#define RC5_TIM_PRESCALER 2
__IO uint8_t EdgesNumber = 0; /* To count the first edges of the frame (max 3 edges) */
StatusYesOrNo Bit4_HasBeen_Sampled = NO; /* To know if the next sampling will be after 3/4 bit time or one bit time */
StatusYesOrNo RC5_FrameReceived = NO; /* Will be used by the user to check if an RC5 has been received or not */
BitTimigStatus BitTimeStatus = OK; /* Variable to store the timing status of the first low duration */
__IO uint8_t FieldBit = 0; /* Bit field value (command between 0-63 or 64-127 */
__IO uint16_t RC5_data[13]; /* Table that contains the value of the GPIOx_IDR register each sampling */
uint8_t RC5_Indexdata = 0; /* Variable that increments each time a RC5 bit is sampled */
__IO uint16_t LowDuration = 0; /* Contains the first low duration in in TIM count */
__IO uint32_t RC5_TIM_CLKValuekHz = 0; /* Contains the frequency input of RC5_TIM in Khz */
uint16_t HalfBitDurationCount_Min = 0; /* Minimum Half bit duration in TIM count */
uint16_t HalfBitDurationCount_Max = 0; /* Maximum Half bit duration in TIM count*/
uint16_t NominalHalfBitDurationCount = 0; /* Nominal Half bit duration in TIM count */
uint16_t FullBitDurationCount_Min = 0; /* Minimum Full bit duration in TIM count */
uint16_t FullBitDurationCount_Max = 0; /* Maximum Full bit duration in TIM count */
uint16_t NominalBitDurationCount = 0; /* Nominal Full bit duration in TIM count */
uint16_t NominalBitDurationCount_3div4 = 0; /* 3/4 of nominal bit time in TIM count */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Private function prototypes -----------------------------------------------*/
static void RC5_RCC_Configuration(void);
static void RC5_GPIO_Configuration(void);
static void RC5_NVIC_Configuration(void);
static uint32_t RC5_TIM_GetCounterCLKValue(void);
static void RC5_WaitForNextFallingEdge(void);
void RC5_Receiver_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
/* System Clocks Configuration for RC5 reception */
RC5_RCC_Configuration();
/* NVIC configuration for RC5 reception */
RC5_NVIC_Configuration();
/* Configure the GPIO port for RC5 reception */
RC5_GPIO_Configuration();
/* Get frequency input of RC5_TIM in Khz */
RC5_TIM_CLKValuekHz = RC5_TIM_GetCounterCLKValue()/1000;
/* Compute the different timing tolerences in TIM count */
NominalBitDurationCount = (RC5_TIM_CLKValuekHz * NOMINAL_FULL_BIT_TIME_US)/1000;
NominalHalfBitDurationCount = (RC5_TIM_CLKValuekHz * NOMINAL_HALF_BIT_TIME_US)/1000;
HalfBitDurationCount_Min = (RC5_TIM_CLKValuekHz * MIN_HALF_BIT_TIME_US)/1000;
HalfBitDurationCount_Max = (RC5_TIM_CLKValuekHz * MAX_HALF_BIT_TIME_US)/1000;
FullBitDurationCount_Min = (RC5_TIM_CLKValuekHz * MIN_FULL_BIT_TIME_US)/1000;
FullBitDurationCount_Max = (RC5_TIM_CLKValuekHz * MAX_FULL_BIT_TIME_US)/1000;
/* Compute the 3/4 bit time duration in TIM count */
NominalBitDurationCount_3div4 = (NominalBitDurationCount * 3)/4;
/* Enable EXTIx to detect the start bit of the RC5 frame */
EXTI_ClearITPendingBit(RC5_EXTI_LINE);
EXTI_InitStructure.EXTI_Line = RC5_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Wait for next falling edge of RC5 frame */
RC5_WaitForNextFallingEdge();
}
static void RC5_WaitForNextFallingEdge(void)
{
/* Enable EXTI line x */
EXTI->IMR |= RC5_EXTI_LINE;
/* RC5_TIM Configuration ------------------------------------------------------*/
TIM_DeInit(RC5_TIM);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = RC5_TIM_PRESCALER;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(RC5_TIM, &TIM_TimeBaseStructure);
TIM_ClearITPendingBit(RC5_TIM, TIM_IT_Update);
}
void RC5_Sample_Data(void)
{
if (TIM_GetITStatus(RC5_TIM, TIM_IT_Update) != RESET) /* Update event occured */
{
/* Sample RC5 GPIO input */
RC5_data[RC5_Indexdata++] = RC5_GPIO_PORT->IDR & RC5_GPIO_PIN;
if(Bit4_HasBeen_Sampled == NO) /* RC5 bit 4 has been sampled? */
{ /*(to know if the next sampling will be after 3/4 or 1 bit time) */
/* If NO: Set the RC5_TIM auto-reload register to allow the next sampling at 1bit time */
RC5_TIM->ARR = NominalBitDurationCount;
/* Set the variable to yes */
Bit4_HasBeen_Sampled = YES;
}
/* If the number of data reaches 13 (without start bit and field bit and extra bit is sampled: (14-2) + 1) */
if(RC5_Indexdata == 13)
{
/* Initialize the RC5 data index */
RC5_Indexdata = 0;
/* Set this flag software to inform the user that a RC5 frame is ready to be read */
RC5_FrameReceived = YES;
/* Initialize Bit4_HasBeen_Sampled variable for next reception */
Bit4_HasBeen_Sampled = NO;
/* Disable RC5_TIM Update event Interrupt Request */
TIM_ITConfig(RC5_TIM, TIM_IT_Update, DISABLE);
/* Disable RC5_TIM counter */
TIM_Cmd(RC5_TIM, DISABLE);
}
/* Clear RC5_TIM Update event interrupt pending bit */
TIM_ClearITPendingBit(RC5_TIM, TIM_IT_Update);
}
}
void RC5_MeasureFirstLowDuration(void)
{
/* If an edge is detected on RC5 input pin */
if(EXTI_GetITStatus(RC5_EXTI_LINE) != RESET)
{
/* Increment the edges number */
EdgesNumber++;
/* If it was the first edge */
if(EdgesNumber == 1)
{
/* Reset the RC5_TIM counter */
RC5_TIM->CNT = 0;
/* Enable RC5_TIM counter */
TIM_Cmd(RC5_TIM, ENABLE);
}
/* If it was the 2nd edge */
else if(EdgesNumber == 2)
{
/* Disable RC5_TIM counter */
TIM_Cmd(RC5_TIM, DISABLE);
/* Read RC5_TIM counter to get the first low duration */
LowDuration = RC5_TIM->CNT;
/* Reset RC5_TIM counter */
RC5_TIM->CNT = 0;
/* If low duration is between 640祍*TimClk and 1140祍*TimClk (min and max half bit time) */
if ((LowDuration >= HalfBitDurationCount_Min) && (LowDuration <= HalfBitDurationCount_Max))
{
/* Validate the frame, by setting this variable to OK */
BitTimeStatus = OK;
}
/* If low duration is between 1340祍*TimClk and 2220祍*TimClk (min and max full bit time)*/
else if ((LowDuration >= FullBitDurationCount_Min) && (LowDuration <= FullBitDurationCount_Max))
{
/* Disable EXTI line x to avoid jumping to this interrupt while receiving
the RC5 data bits (it will be reenabled in the next RC5 data reception */
EXTI->IMR &= ((uint32_t)~RC5_EXTI_LINE);
/* Enable RC5_TIM counter */
TIM_Cmd(RC5_TIM, ENABLE);
/* Enable RC5_TIM Update Event Interrupt Request */
TIM_ITConfig(RC5_TIM, TIM_IT_Update, ENABLE);
/* Validate the frame, by setting this variable to OK */
BitTimeStatus = OK;
/* Set the RC5_TIM auto-reload register to allow the next sampling at 3/4 bit time */
RC5_TIM->ARR = NominalBitDurationCount_3div4;
/* The bit field value is equal to 0 */
FieldBit = 0;
/* Initialize edges detected number */
EdgesNumber = 0;
}
else /* If the first low duration is not in the right timing range */
{
/* Set the Bit timing to NOTOK */
BitTimeStatus = NOTOK;
/* Reset RC5_TIM counter */
RC5_TIM->CNT = 0;
/* Initialize the number of glitches detected */
EdgesNumber = 0;
}
}
else if(EdgesNumber == 3) /* If the number of edges is equal to 3 */
{
/* Disable EXTI line x to avoid jumping to this interrupt while receiving
the RC5 data bits (it will be reenabled in the next RC5 data reception */
EXTI->IMR &= ((uint32_t)~RC5_EXTI_LINE);
/* Enable RC5_TIM counter */
TIM_Cmd(RC5_TIM, ENABLE);
/* Enable RC5_TIM Update Event Interrupt Request */
TIM_ITConfig(RC5_TIM, TIM_IT_Update, ENABLE);
/* Validate the frame, by setting this variable to OK */
BitTimeStatus = OK;
/* Set the RC5_TIM auto-reload register to allow the next sampling at 3/4 bit time */
RC5_TIM->ARR = NominalBitDurationCount_3div4;
/* The bit field value is equal to 1 */
FieldBit = 1;
/* Initialize the number of glitches detected */
EdgesNumber = 0;
}
/* Clear the RC5 EXTI line pending bit */
EXTI_ClearITPendingBit(RC5_EXTI_LINE);
}
}
RC5Frame_TypeDef RC5_Decode(void)
{
RC5Frame_TypeDef RC5_frame_struct;
uint32_t RC5_dataIndex = 0;
/* Initialize the different fields of the RC5 structure */
RC5_frame_struct.ToggleBit = 0;
RC5_frame_struct.Address = 0;
RC5_frame_struct.Command = 0;
/* Get the Toggle bit value */
if(RC5_data[0] & RC5_GPIO_PIN)
{
RC5_frame_struct.ToggleBit = 1;
}
else
{
RC5_frame_struct.ToggleBit = 0;
}
/* Get RC5 Address value */
for(RC5_dataIndex=1; RC5_dataIndex<6; RC5_dataIndex++)
{
RC5_frame_struct.Address <<= 1 ;
if(RC5_data[RC5_dataIndex] & RC5_GPIO_PIN)
{
RC5_frame_struct.Address |= 1;
}
}
/* Get RC5 Command value */
for(RC5_dataIndex=6; RC5_dataIndex<12; RC5_dataIndex++)
{
RC5_frame_struct.Command <<= 1 ;
if(RC5_data[RC5_dataIndex] & RC5_GPIO_PIN)
{
RC5_frame_struct.Command |= 1;
}
}
/* Set the 6th bit of the command regarding of the filed bit value */
if(FieldBit == 0) /* logic 0 = command from 64 to 127 */
{
RC5_frame_struct.Command |= 0x40;
}
/* Initialize RC5_FrameReceived for next RC5 reception */
RC5_FrameReceived = NO;
/* Wait for next falling edge of RC5 frame*/
RC5_WaitForNextFallingEdge();
/* Return the RC5 struct */
return RC5_frame_struct;
}
static void RC5_RCC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RC5_TIM_CLK, ENABLE);
}
/* GPIOx clock enable for RC5 input pin */
RCC_APB2PeriphClockCmd(RC5_GPIO_CLK | RCC_APB2Periph_AFIO , ENABLE);
}
static void RC5_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* RC5 pin configuration: input floating */
GPIO_InitStructure.GPIO_Pin = RC5_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(RC5_GPIO_PORT, &GPIO_InitStructure);
/* Connect EXTI Line x to RC5 pin */
GPIO_EXTILineConfig(RC5_EXTI_PORT_SOURCE, RC5_EXTI_PIN_SOURCE);
}
static void RC5_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the EXTIx global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RC5_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the RC5_TIM global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RC5_TIM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static uint32_t RC5_TIM_GetCounterCLKValue(void)
{
uint32_t apbprescaler = 0, apbfrequency = 0;
RCC_ClocksTypeDef RCC_ClockFreq;
RCC_GetClocksFreq(&RCC_ClockFreq);
{
/* Get the clock prescaler of APB1 */
apbprescaler = ((RCC->CFGR >> 8) & 0x7);
apbfrequency = RCC_ClockFreq.PCLK1_Frequency;
}
/* If APBx clock div >= 4 */
if (apbprescaler >= 4)
{
return ((apbfrequency * 2)/(RC5_TIM_PRESCALER + 1));
}
else
{
return (apbfrequency/(RC5_TIM_PRESCALER + 1));
}
}
//main.C
#include "stm32f10x.h"
#include "RC5_IR_Emul_Receiver.h"
#include "lcd12864.h"
#include <stdio.h>
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
const char* RC5_Devices[32] = {
"TV1" , /* 0 */
"TV2" , /* 1 */
"Video Text" , /* 2 */
"Extension TV", /* 3 */
"LaserVideoPlayer", /* 4 */
"VCR1", /* 5 */
"VCR2", /* 6 */
"Reserved", /* 7 */
"Sat1", /* 8 */
"Extension VCR", /* 9 */
"Sat2", /* 10 */
"Reserved", /* 11 */
"CD Video", /* 12 */
"Reserved", /* 13 */
"CD Photo", /* 14 */
"Reserved", /* 15 */
"Preampli Audio 1", /* 16 */
"Tuner", /* 17 */
"Analog Magneto", /* 18 */
"Preampli Audio 2", /* 19 */
"CD", /* 20 */
"Rack Audio", /* 21 */
"Audio Sat Receiver", /* 22 */
"DDC Magneto", /* 23 */
"Reserved", /* 24 */
"Reserved", /* 25 */
"CDRW", /* 26 */
"Reserved", /* 27 */
"Reserved", /* 28 */
"Reserved", /* 29 */
"Reserved", /* 30 */
"Reserved" /* 31 */
};
/* Table of different commands (TV) */
const char* RC5_Commands[128] = {
"Num0", /* 0 */
"Num1", /* 1 */
"Num2", /* 2 */
"Num3", /* 3 */
"Num4", /* 4 */
"Num5", /* 5 */
"Num6", /* 6 */
"Num7", /* 7 */
"Num8", /* 8 */
"Num9", /* 9 */
"TV Digits", /* 10 */
"TV Freq", /* 11 */
"TV StandBy", /* 12 */
"TV Mute On-Off", /* 13 */
"TV Preference", /* 14 */
"TV Display", /* 15 */
"Volume Up", /* 16 */
"Volume Down", /* 17 */
"Brightness Up", /* 18 */
"Brightness Down", /* 19 */
"Color Saturation Up", /* 20 */
"Color Saturation Down", /* 21 */
"Bass Up", /* 22 */
"Bass Down", /* 23 */
"Treble Up", /* 24 */
"Treble Down", /* 25 */
"Balance Right", /* 26 */
"BalanceLeft", /* 27 */
"TV Contrast Up", /* 28 */
"TV Contrast Down", /* 29 */
"TV Search Up", /* 30 */
"TV tint-hue Down", /* 31 */
"TV CH Prog Up", /* 32 */
"TV CH ProgDown", /* 33 */
"TV Last viewed program-channel", /* 34 */
"TV Select stereo sound channel-language", /* 34 */
"TV Spacial Stereo", /* 36 */
"TV Stereo Mono", /* 37 */
"TV Sleep Timer", /* 38 */
"TV tint-hue Up", /* 39 */
"TV RF Switch", /* 40 */
"TV Store-VOTE", /* 41 */
"TV Time", /* 42 */
"TV Scan Fwd Inc", /* 43 */
"TV Decrement", /* 44 */
"Reserved", /* 45 */
"TV Secondary control-menu", /* 46 */
"TV Show Clock", /* 47 */
"TV Pause", /* 48 */
"TV Erase Correct Entry", /* 49 */
"TV Rewind", /* 50 */
"TV Goto", /* 51 */
"TV Wind", /* 52 */
"TV Play", /* 53 */
"TV Stop", /* 54 */
"TV Record", /* 55 */
"TV External 1", /* 56 */
"TV External 2", /* 57 */
"Reserved", /* 58 */
"TV Advance", /* 59 */
"TV TXT-TV toggle", /* 60 */
"TV System StandBy", /* 61 */
"TV Picture Crispener", /* 62 */
"System Select", /* 63 */
"Reserved", /* 64 */
"Reserved", /* 65 */
"Reserved", /* 66 */
"Reserved", /* 67 */
"Reserved", /* 68 */
"Reserved", /* 69 */
"TV Speech Music", /* 70 */
"DIM Local Display", /* 71 */
"Reserved", /* 72 */
"Reserved", /* 73 */
"Reserved", /* 74 */
"Reserved", /* 75 */
"Reserved", /* 76 */
"Increase Linear Control Setting", /* 77 */
"Decrease Linear Control Setting", /* 78 */
"TV Sound Scroll", /* 79 */
"Step Up", /* 80 */
"Step Down", /* 81 */
"Menu On", /* 82 */
"Menu Off", /* 83 */
"AV Status", /* 84 */
"Step Left", /* 85 */
"Step Right", /* 86 */
"Acknowledge", /* 87 */
"PIP On Off", /* 88 */
"PIP Shift", /* 89 */
"PIP Main Swap", /* 90 */
"Strobe On Off", /* 91 */
"Multi Strobe", /* 92 */
"Main Frozen", /* 93 */
"3div9 Multi scan", /* 94 */
"PIPSelect", /* 95 */
"MultiPIP", /* 96 */
"Picture DNR", /* 97 */
"Main Stored", /* 98 */
"PIP Strobe", /* 99 */
"Recall Main Stored Picture", /* 100 */
"PIP Freeze", /* 101 */
"PIP Step Up", /* 102 */
"PIP Step Down", /* 103 */
"TV PIP Size", /* 104 */
"TV Picture Scroll", /* 105 */
"TV Actuate Colored Or Other Special Keys", /* 106 */
"TV Red", /* 107 */
"TV Green", /* 108 */
"TV Yellow", /* 109 */
"TV Cyan", /* 110 */
"TV Index White", /* 111 */
"TV Next", /* 112 */
"TV Previous", /* 113 */
"Reserved", /* 114 */
"Reserved", /* 115 */
"Reserved", /* 116 */
"Reserved", /* 117 */
"Sub Mode", /* 118 */
"Option Sub Mode", /* 119 */
"Reserved", /* 120 */
"Reserved", /* 121 */
"TV Store Open Close", /* 122 */
"Connect", /* 123 */
"Disconnect", /* 124 */
"Reserved", /* 125 */
"TV Movie Expand", /* 126 */
"TV Parental Access" /* 127 */
};
extern StatusYesOrNo RC5_FrameReceived;
RC5Frame_TypeDef RC5_Frame;
uint8_t RC5_TogglePrevious = 0;
StatusYesOrNo FirstTimeIssued = YES;
void RCC_Configuration(void);
void USART_Configuration(void);
void Delay(u16 speed);
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
RCC_ClocksTypeDef RCC_ClockFreq;
int main(void)
{ RCC_Configuration();
RC5_Receiver_Init();
USART_Configuration();
GPIO_Configuration();
LcdInit();
TestLCDS();
printf("\n\r\n STM32 ARM开发板 DIY RC5 红外线遥控解码演示\n\r");
while (1)
{
if (RC5_FrameReceived == YES)
{
RC5_Frame = RC5_Decode();
if(FirstTimeIssued == YES)
{
RC5_TogglePrevious = ~(RC5_Frame.ToggleBit)&0x01;
FirstTimeIssued = NO;
}
if(RC5_Frame.ToggleBit != RC5_TogglePrevious)
{
printf("\n\rRC5 Toggle bit: %d \n\r",RC5_Frame.ToggleBit);
printf("RC5 Address: %s ",RC5_Devices[RC5_Frame.Address]);
printf("(%d) \n\r",RC5_Frame.Address);
printf("RC5 Command: %s",RC5_Commands[RC5_Frame.Command]);
printf("(%d) \n\r",RC5_Frame.Command);
byte_disp(6,11,RC5_Frame.Command/10+'0');
byte_disp(6,12,RC5_Frame.Command%10+'0');
RC5_TogglePrevious = RC5_Frame.ToggleBit;
}
}
__WFI();
}
}
void RCC_Configuration(void)
{
/* Setup the microcontroller system. Initialize the Embedded Flash Interface,
initialize the PLL and update the SystemFrequency variable. */
SystemInit();
RCC_GetClocksFreq(&RCC_ClockFreq);
}
void Delay(u16 speed)
{
u16 i;
while(speed!=0)
{
speed--;
for(i=0;i<400;i++);
}
}
ARM DIY 已经接近尾声了,感谢EEPW给我们提供一个很好的平台,让我们在学习STM32过程中互相交流、锻炼了能力、增长了知识。在这里将这次DIY动手过程中因硬件原因而影响进程的例子与大家分享,希望能加速各位的进程。
CAN:
1、 CAN双机通信调试中,牵涉到硬件和软件2部分,任何一处出问题都会影响到调试的顺利进行,由于板上1只小小的电阻,让zangchao童鞋走了弯路。浪费了不少时间:在开发板上CAN通信IC VD230的第8脚如果在高电平状态,就要影响发送了,虽然在原理图中有这样一句“Default do not fit”,但是一般我们在焊接零件时是不会去注意的,会把R51一起焊上去。这样就造成U7第8脚高电平,数据发送不出去。处理方法可点击下面的分享链接。
2、如果有示波器观察输出波形(点击进入),要注意必须让2台机器的通信节点连接正常,否则仍然检测不到输出波形的。
3、双机通信要在单机自循环成功后才进行,可以预先排除单机的故障,使调试少走弯路。发送应该设计成按了某一按键后才进行,按键放开后就处于接收状态。
有关CAN的调试过程,包括单机自循环模式的工程文件,点击CAN调试分享进入。
USB:
在开发板上的USB接口D+的第3脚如果处于低电平,PC机端口是识别不到USB的。而开发板上该脚的直流电平是由T1来控制的。T1基极通过R47和JP2受控于PA10,在原理图中JP2缺省状态是开路,这样T1将无法导通,USB口第3脚处于低电平,USB功能将失效。而当你记得将JP2短接,但忘了让PA10为输出口并输出高电平时,USB同样无效。
解决方法点击USB调试分享进入。
ADC
ADC出现硬件毛病是非常不幸让我撞上的,开始时ADC转换结果总是0xFFF。找了很久才发现3.3V通往CPU的REF基准电压丢了。最后发现是过孔断裂,还好在CPU边上,没有被其遮挡住,才得以补救回来。
点击ADC故障进入。
SD卡
开发板的SD卡只能工作于4总线方式,在我的编译环境下4总线SD卡却屡试屡败,改用SPI方式(点击进入)才成功。
回复
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |