stm32 读保护输出模式可以读管脚状态吗

查看: 7227|回复: 15
stm32 用TIM3输出pwm 我把PB01,PB02分别作为PWM1通道3,4是可以有输出的,但是如果用PA0,P
我把可以工作的代码稍微替换了一下管脚就没有输出了。修改如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
& && && && && && && && & | RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC
& && && && && && && && & | RCC_APB2Periph_AFIO,ENABLE);
/****************pwm******PB.00*PB.01************/
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOB, &GPIO_InitStructure);
/****************pwm******PA.00*PA.01************/
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOA, &GPIO_InitStructure);
我把PB01,PB02分别作为PWM1通道3,4是可以有输出的,但是如果用PA0,PA1,为什么就不可以了,是不是输出管脚是有限制de ?
随便一个GPIO口是否都可以作为PWM的输出啊?有什么注意的地方?
可以工作的代码如下(PB1,PB0)
/* Includes ------------------------------------------------------------------*/
#include &stm32f10x_lib.h&
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void SysTick_Config(void);
void PWM_Configuration(void);
void delay_nus(u32 us);
/////////////////////////////////////////////////
TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
TIM_OCInitTypeDef&&TIM_OCInitS
u16 CCR3_Val = 250;//使低电平持续时间5ms
u16 CCR4_Val = 250;
///////////////////////////////////////
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name&&: main
* Description& & : Main program.
* Input& && && & : None
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
int main(void)
#ifdef DEBUG
&&debug();
&&/* System Clocks Configuration */
&&RCC_Configuration();
&&/* NVIC configuration */
&&NVIC_Configuration();
&&/* Configure the GPIO ports */
&&GPIO_Configuration();
&&PWM_Configuration();
&&/* Connect EXTI Line3 to PC.03 */
&&GPIOB-&BSRR = 0X0f00;//关闭led
///////////////////////////////////////////////////////////////////////////////
&&EXTI_InitTypeDef EXTI_InitS
&&GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);
&&/* Configure EXTI Line4 to generate an interrupt on falling edge */&&
&&EXTI_InitStructure.EXTI_Line = EXTI_Line1;
&&EXTI_InitStructure.EXTI_Mode = EXTI_Mode_I
&&EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_F
&&EXTI_InitStructure.EXTI_LineCmd = ENABLE;
&&EXTI_Init(&EXTI_InitStructure);
&&/* Generate software interrupt: simulate a falling edge applied on EXTI line 3 */
&&EXTI_GenerateSWInterrupt(EXTI_Line1);
////////////////////////////////////////////////////////////////////////////////& &
&&while (1)
& && && &{
& && && &}&&
/////////////////////////////////////////////////////////////////////
/*******************************************************************************
* Function Name&&: RCC_Configuration
* Description& & : Configures the different system clocks.
* Input& && && & : None
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
void RCC_Configuration(void)
&&ErrorStatus HSEStartUpS
&&/* RCC system reset(for debug purpose) */
&&RCC_DeInit();
&&/* Enable HSE */
&&RCC_HSEConfig(RCC_HSE_ON);
&&/* Wait till HSE is ready */
&&HSEStartUpStatus = RCC_WaitForHSEStartUp();
&&if(HSEStartUpStatus == SUCCESS)
& & /* Enable Prefetch Buffer */
& & FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
& & /* Flash 2 wait state */
& & FLASH_SetLatency(FLASH_Latency_2);
& & /* HCLK = SYSCLK */
& & RCC_HCLKConfig(RCC_SYSCLK_Div1);
& & /* PCLK2 = HCLK */
& & RCC_PCLK2Config(RCC_HCLK_Div1);
& & /* PCLK1 = HCLK/2 */
& & RCC_PCLK1Config(RCC_HCLK_Div2);
& & /* PLLCLK = 8MHz * 9 = 72 MHz */
& & RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
& & /* Enable PLL */
& & RCC_PLLCmd(ENABLE);
& & /* Wait till PLL is ready */
& & while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
& & /* Select PLL as system clock source */
& & RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
& & /* Wait till PLL is used as system clock source */
& & while(RCC_GetSYSCLKSource() != 0x08)
&&/* Enable GPIOB, GPIOC and AFIO clock */
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
& && && && && && && && & | RCC_APB2Periph_AFIO,ENABLE);
&&RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE);& & //启用TIME3-&PWM&&
/*******************************************************************************
* Function Name&&: GPIO_Configuration
* Description& & : Configures the different GPIO ports.
* Input& && && & : None
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
void GPIO_Configuration(void)
&&GPIO_InitTypeDef GPIO_InitS
&&/* Configure PB.08 as Output push-pull */
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
&&GPIO_Init(GPIOB, &GPIO_InitStructure);
&&/* Configure PC.01 as input floating (EXTI Line 1) */
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
&&GPIO_Init(GPIOC, &GPIO_InitStructure);
&&/****************pwm******PB.00*PB.01************/
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOB, &GPIO_InitStructure);
/*******************************************************************************
* Function Name&&: NVIC_Configuration
* Description& & : Configure the nested vectored interrupt controller.
* Input& && && & : None
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
void NVIC_Configuration(void)
&&NVIC_InitTypeDef NVIC_InitS
#ifdef&&VECT_TAB_RAM&&
&&/* Set the Vector Table base location at 0x */
&&NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else&&/* VECT_TAB_FLASH&&*/
&&/* Set the Vector Table base location at 0x */
&&NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);& &
&&/* Configure one bit for preemption priority */
&&NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
&&/* Enable the EXTI1 Interrupt */
&&NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQC
&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
&&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
&&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
&&NVIC_Init(&NVIC_InitStructure);
////////////////////////////////////////////////////////////
//SysTick设置
void SysTick_Config(void)
& & /* Disable SysTick Counter */
& & SysTick_CounterCmd(SysTick_Counter_Disable);
& & /* Disable the SysTick Interrupt */
& & SysTick_ITConfig(DISABLE);
& & /* Configure HCLK clock as SysTick clock source */
& & SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
& & /* SysTick interrupt each 1000 Hz with HCLK equal to 72MHz */
& & SysTick_SetReload(9000);& &
& & /* Enable the SysTick Interrupt */
& & SysTick_ITConfig(ENABLE);
& & /* Enable the SysTick Counter */
& &//SysTick_CounterCmd(SysTick_Counter_Enable);& &
//////////////////////PWN**********配置//////////////////////////////////////
void PWM_Configuration(void)
&&/* -----------------------------------------------------------------------
& & TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
& & TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
& & TIM3 ARR Register = 999 =& TIM3 Frequency = TIM3 counter clock/(ARR + 1)
& & TIM3 Frequency = 36 KHz.
& & TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
& & TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
& & TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
& & TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
&&----------------------------------------------------------------------- */
/* Time base configuration */
&&TIM_TimeBaseStructure.TIM_Period = 750;//自动重装载寄存器周期的值&&即是PWM方波的周期=7.5ms
&&TIM_TimeBaseStructure.TIM_Prescaler = 0x1c1f;//100us时钟频率 (72/(预分频数+1)
&&TIM_TimeBaseStructure.TIM_ClockDivision = 0;
&&TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
&&TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
&&TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&/* PWM1 Mode configuration: Channel3 */
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&TIM_OCInitStructure.TIM_Pulse = CCR3_V//CCR3_Val=
&&TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H//比较输出高电平
&&TIM_OC3Init(TIM3, &TIM_OCInitStructure);
&&TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
&&/* PWM1 Mode configuration: Channel4 */
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&TIM_OCInitStructure.TIM_Pulse = CCR4_V// CCR4_Val=
&&TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H//比较输出高电平
&&TIM_OC4Init(TIM3, &TIM_OCInitStructure);//使能 TIMx在 CCR4 上的预装载寄存器
&&TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
&&//TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);& & & &&&//设置单脉冲模式
&&TIM_ARRPreloadConfig(TIM3, ENABLE);
&&/* TIM3 enable counter */
&&TIM_Cmd(TIM3, ENABLE);&&
////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
void delay_nus(u32 us)
& & while(us--)
& && & i=7;& && && && & //1us
& && & while(i--);
///////////////////////////////////////////////////////////////////////
#ifdef&&DEBUG
/*******************************************************************************
* Function Name&&: assert_failed
* Description& & : Reports the name of the source file and the source line number
*& && && && && && &where the assert_param error has occurred.
* Input& && && & : - file: pointer to the source file name
*& && && && && && &- line: assert_param error line source number
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
&&/* User can add his own implementation to report the file name and line number,
& &&&ex: printf(&Wrong parameters value: file %s on line %d\r\n&, file, line) */
&&/* Infinite loop */
&&while (1)
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
不懂,帮顶!
STM32的管脚对然上说,可以复用,但是呢!并不是说,任何一个管脚都可以随便用的,比如你刚开始有PWM输出的PB0.0 PB0.1默认对应的是TIM3_CH3,TIM3_CH4,正好是你代码中配置的那样,是正确的配置,所以自然有PWM输出。但是你改为PA0.0 PA0.1以后,那就不一样了。
PA0.1=========TIM2_CH2通道。PA0.0======TIM2_CH1,所以你要更改你的代码。如下。
void PWM_Configuration(void)
& &这里的TIM3都要改成TIM2
=================================================================================
TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:&&==============TIM2
& & TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
& & TIM3 ARR Register = 999 =& TIM3 Frequency = TIM3 counter clock/(ARR + 1) ===============TIM2
& & TIM3 Frequency = 36 KHz.
& & TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50% ================TIM2
& & TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
& & TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
& & TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
===========================================================================
然后在中断处理程序中将对应的通道改为:CH1&&CH2.
不知道明白没有?
公益广告:本论坛不得使用、宣传Q群。 有讨论请在论坛里进行。 违者将封锁ID.
楼上正解,复用并不是外设引脚随便配置,而指的是一个引脚有多个外设公用,但是任何一个时刻只能有一个外设使用它。而且目前STM除了外部中断是可以随便配置引脚之外,其他外设顶多有一个重映射的备用引脚,没有你想象的那么灵活。
公益广告:发表招聘帖子需要缴费,有需要可以联系网站工作人员王小姐:.
是啊 在设计硬件的时候就要考虑到这些。不然!不要想当然了。蕊片不是万能的。
不过STM32提供了一个重映射复用功能引脚,还是比较灵活的了。
公益广告:广告只能发在本论坛的广告区,否则将封锁ID。
回复【2楼】flyforyou85
-----------------------------------------------------------------------
恩 谢谢你的帮助 明白了 ,刚刚看了一下手册,看了一下默认的配置,果然是那样的,看来还是要仔细看看数据手册才可以的。
定时器管脚复用功能重映射 (原文件名:timer.png)
学习了,谢谢。
我试了一下,用tim2的1,2通道时可以输出pwm的 ,可是配置成3,4通道却没有了,还没有找到原因。
回复【3楼】tiancaigao7 天才杨威利
-----------------------------------------------------------------------
请问我按照二楼的所说的,更改了一下,tim2的1,2通道时可以工作的,但是开启3,4通道就没有输出了,哪里又出问题了?
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC
& && && && && && && && & | RCC_APB2Periph_AFIO,ENABLE);
&&RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);& & //启用TIME2-&PWM&&
/****************pwm******************/
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
&&GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
&&GPIO_Init(GPIOA, &GPIO_InitStructure);
----------------------------------------------------------------------- */
TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
TIM_OCInitTypeDef&&TIM_OCInitS
&&/* Time base configuration */
&&TIM_TimeBaseStructure.TIM_Period = 750;//自动重装载寄存器周期的值&&即是PWM方波的周期=7.5ms
&&TIM_TimeBaseStructure.TIM_Prescaler = 0x1c1f;//100us时钟频率 (72/(预分频数+1)
&&TIM_TimeBaseStructure.TIM_ClockDivision = 0;
&&TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
&&TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
&&TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&/* PWM1 Mode configuration: Channel3 */
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&TIM_OCInitStructure.TIM_Pulse = CCR3_V//CCR3_Val=
&&TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H//比较输出高电平
&&TIM_OC3Init(TIM2, &TIM_OCInitStructure);
&&TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
&&/* PWM1 Mode configuration: Channel4 */
&&TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
&&TIM_OCInitStructure.TIM_Pulse = CCR4_V// CCR4_Val=
&&TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H//比较输出高电平
&&TIM_OC4Init(TIM2, &TIM_OCInitStructure);//使能 TIMx在 CCR4 上的预装载寄存器
&&TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
&&TIM_SelectOnePulseMode(TIM2, TIM_OPMode_Single);& & & &&&//设置单脉冲模式
&&TIM_ARRPreloadConfig(TIM2, ENABLE);
&&/* TIM3 enable counter */
&&TIM_Cmd(TIM2, ENABLE);&&
上面几楼说得对的.
(1)定时器通道的管脚是定下的,不能随意改动.我现在用的是STM32f103c8,其它的查相应手册.
详细配置如下:TIM1_CH1-&PA8; TIM1_CH2-&PA9; TIM1_CH3-&PA10; TIM1_CH4-&PA11;
& && && && & TIM2_CH1-&PA0; TIM2_CH2-&PA1; TIM2_CH3-&PA2; TIM2_CH4-&PA3;
& && && && & TIM3_CH1-&PA6; TIM3_CH2-&PA7; TIM3_CH3-&PB0; TIM3_CH4-&PB1;
& && && && & TIM4_CH1-&PB6; TIM4_CH1-&PB7; TIM4_CH1-&PB8; TIM4_CH1-&PB9;
(2)不是所有的芯片都有重映像功能的,STM32f103c8这四个定时器就不需要重映像.
(3)定时器输出需要设置向个模块:
& &1)相应时钟要使能,包括TIMx,GPIO(用到哪个可以开哪个,初学者也可以全开起,免得多事;
& &比如说:用TIM4
& && && &RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
& & & & RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
&&2)GPIO相应管脚模式设置
& && && &GPIO_InitTypeDef GPIO_InitS
& && && &GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
&&& & & & GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
&&& & & & GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
&&& & & & GPIO_Init(GPIOB,&GPIO_InitStructure);
&&3)定时器设置(下面的例子是产生4个通道的PWM)
void TIM_Configuration(void)
TIM_TimeBaseInitTypeDef& &TIM_TimeBaseS
TIM_OCInitTypeDef& && & & && & TIM_OCInitS
TIM_DeInit(TIM4);
TIM_TimeBaseStructure.TIM_Period=144;& & & & & & & &&&//ARR的值
TIM_TimeBaseStructure.TIM_Prescaler=4000;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM4, ENABLE);//使能ARR预装载缓冲器
& & & & /* Channel 1 Configuration in PWM mode */
& & & & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; & & & & & & & & & & & & & & & & //PWM模式2
& & & & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E & & & & //正向通道有效
& & & & TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_D//反向通道无效
& & & & TIM_OCInitStructure.TIM_Pulse = 120; & & & & & & & & & & & & & & & & & & & & & & & & & & & & //占空时间
& & & & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_L & & & & & & & & //输出极性
& & & & TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_H& &&&//互补端的极性&&
& & & & TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_S
& & & & TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_R&&
& & & & TIM_OC1Init(TIM4,&TIM_OCInitStructure); & & & & & & & & & & & & & & & & & & & & & & & & //通道1
& & & & TIM_OCInitStructure.TIM_Pulse = 80; & & & & & & & & & & & & & & & & & & & & & & & & & & & & //占空时间
& & & & TIM_OC2Init(TIM4,&TIM_OCInitStructure); & & & & & & & & & & & & & & & & & & & & & & & & //通道2
& & & & TIM_OCInitStructure.TIM_Pulse = 40; & & & & & & & & & & & & & & & & & & & & & & & & & & & & //占空时间
& & & & TIM_OC3Init(TIM4,&TIM_OCInitStructure); & & & & & & & & & & & & & & & & & & & & & & & & //通道3
& & & & TIM_OCInitStructure.TIM_Pulse = 20; & & & & & & & & & & & & & & & & & & & & & & & & & & & & //占空时间
& & & & TIM_OC4Init(TIM4,&TIM_OCInitStructure); & & & & & & & & & & & & & & & & & & & & & & & & //通道4
& & & & /* TIM1 counter enable */
& & & & TIM_Cmd(TIM4,ENABLE);
& & & & /* TIM1 Main Output Enable */
& & & & TIM_CtrlPWMOutputs(TIM4,ENABLE);
因为自己也是初学,很感谢网络上朋友的支持和帮助.也想贡献自己的一点点力量,希望对初学者有帮助.
阿莫电子论坛, 原"中国电子开发网"所属子分类:
注册时间: 21:31
论坛积分:20
STM32 CAN收发 PA11&PA12回环OK ,正常模式无数据发送,引脚无波形输出
请各位大侠指点,以下是我的代码
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "misc.h"
#include "stm32f10x_can.h"
#include "stm32f10x_gpio.h"
#define CAN_BAUDRATE 500
/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestS
__IO uint32_t ret = 0; /* for return of the interrupt handling */
volatile TestStatus TestRx;
/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
TestStatus CAN_Polling(void);
TestStatus CAN_Interrupt(void);
/****************************************************************************
* 名 & &称:int main(void)
* 功 & &能:主函数
* 入口参数:无
* 出口参数:无
* 说 & &明:
* 调用方法:无&
****************************************************************************/&
int main(void)
& RCC_Configuration();
& //系统时钟设置及外设时钟使能
& NVIC_Configuration();
& //中断源配置 &
& /* CAN 500KB/s中断方式下的收发---正常通信模式 */
& while (1);
/****************************************************************************
* 名 & &称:void RCC_Configuration(void)
* 功 & &能:系统时钟配置为72MHZ, 外设时钟配置
* 入口参数:无
* 出口参数:无
* 说 & &明:
* 调用方法:无&
****************************************************************************/&
void RCC_Configuration(void){
& SystemInit();&
& RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
& RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1|RCC_APB1Periph_CAN2, ENABLE);
& RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC&
| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE);
/****************************************************************************
* 名 & &称:void NVIC_Configuration(void)
* 功 & &能:中断源配置
* 入口参数:无
* 出口参数:无
* 说 & &明:
* 调用方法:无&
****************************************************************************/
void NVIC_Configuration(void)
& NVIC_InitTypeDef NVIC_InitS
& NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
& //CAN1 RX0中断
& NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
& //抢占优先级0
& NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& //子优先级为0
& NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& NVIC_Init(&NVIC_InitStructure);
/****************************************************************************
* 名 & &称:TestStatus CAN_Interrupt(void)
* 功 & &能:中断模式下的CAN收发
* 入口参数:无
* 出口参数:无
* 说 & &明:
* 调用方法:无&
****************************************************************************/
TestStatus CAN_Interrupt(void)
& CAN_InitTypeDef & & & &CAN_InitS
& CAN_FilterInitTypeDef &CAN_FilterInitS &
& GPIO_InitTypeDef &GPIO_InitS
& CanTxMsg TxM
& //CanRxMsg RxM
& //uint8_t TransmitMailbox = 0;
& GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
& & //端口复用为CAN1 &&
& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
& & & & & & & & //PA11:CAN-RX&
& GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
& & //输入上拉
& GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& GPIO_Init(GPIOA, &GPIO_InitStructure);
& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
//PA12:CAN-TX&
& GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//复用模式
& GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& GPIO_Init(GPIOA, &GPIO_InitStructure);
& /* CAN寄存器初始化 */
& CAN_DeInit(CAN1);
& CAN_StructInit(&CAN_InitStructure);
& /* CAN单元初始化 */
& CAN_InitStructure.CAN_TTCM=DISABLE;
& //MCR-TTCM &时间触发通信模式使能
& CAN_InitStructure.CAN_ABOM=DISABLE;
& //MCR-ABOM &自动离线管理&
& CAN_InitStructure.CAN_AWUM=DISABLE;
& //MCR-AWUM &自动唤醒模式
& //CAN_InitStructure.CAN_NART=ENABLE;
& //MCR-NART &禁止报文自动重传
&0-自动重传 & 1-报文只传一次
& CAN_InitStructure.CAN_NART=DISABLE;
& //MCR-NART &禁止报文自动重传
&0-自动重传 & 1-报文只传一次
& CAN_InitStructure.CAN_RFLM=DISABLE;
& //MCR-RFLM &接收FIFO 锁定模式 &0-溢出时新报文会覆盖原有报文 &1-溢出时,新报文丢弃
& CAN_InitStructure.CAN_TXFP = ENABLE;
& CAN_InitStructure.CAN_Mode = CAN_Mode_N
& //CAN_InitStructure.CAN_TXFP=DISABLE;
& //MCR-TXFP &发送FIFO优先级 0-优先级取决于报文标示符 1-优先级取决于发送请求的顺序
& //CAN_InitStructure.CAN_Mode=CAN_Mode_LoopB
& //BTR-SILM/LBKM & CAN环回模式
& CAN_InitStructure.CAN_SJW=CAN_SJW_1
& //BTR-SJW 重新同步跳跃宽度 1个时间单元
& CAN_InitStructure.CAN_BS1=CAN_BS1_2
& //BTR-TS1 时间段1 占用了2个时间单元
& CAN_InitStructure.CAN_BS2=CAN_BS2_3
& //BTR-TS1 时间段2 占用了3个时间单元
#if CAN_BAUDRATE == 1000 /* 1MBps */
& CAN_InitStructure.CAN_Prescaler =6;
& //BTR-BRP 波特率分频器 &定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
#elif CAN_BAUDRATE == 500 /* 500KBps */
& CAN_InitStructure.CAN_Prescaler =12;
#elif CAN_BAUDRATE == 250 /* 250KBps */
& CAN_InitStructure.CAN_Prescaler =24;
#elif CAN_BAUDRATE == 125 /* 125KBps */
& CAN_InitStructure.CAN_Prescaler =48;
#elif &CAN_BAUDRATE == 100 /* 100KBps */
& CAN_InitStructure.CAN_Prescaler =60;
#elif &CAN_BAUDRATE == 50 /* 50KBps */
& CAN_InitStructure.CAN_Prescaler =120;
#elif &CAN_BAUDRATE == 20 /* 20KBps */
& CAN_InitStructure.CAN_Prescaler =300;
#elif &CAN_BAUDRATE == 10 /* 10KBps */
& CAN_InitStructure.CAN_Prescaler =600;
& //CAN_InitStructure.CAN_TXFP=DISABLE;
& //CAN_InitStructure.CAN_Mode=CAN_Mode_LoopB
// &CAN_InitStructure.CAN_SJW=CAN_SJW_1
// &CAN_InitStructure.CAN_BS1=CAN_BS1_8
// &CAN_InitStructure.CAN_BS2=CAN_BS2_7
& //CAN_InitStructure.CAN_Prescaler=1;
& CAN_Init(CAN1, &CAN_InitStructure);
& /* CAN过滤器初始化 */
& CAN_FilterInitStructure.CAN_FilterNumber=0;
& CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdM
//FM1R &过滤器组0的工作模式。
//0: 过滤器组x的2个32位寄存器工作在标识符屏蔽位模式;&
//1: 过滤器组x的2个32位寄存器工作在标识符列表模式。
& CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32 //FS1R 过滤器组0(13~0)的位宽。
//0:过滤器位宽为2个16位; 1:过滤器位宽为单个32位。
& /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */
& CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)0xxFFFF0000)&&16;
//要过滤的ID高位&
& CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)0x1234&&3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;//要过滤的ID低位&
& CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0
& CAN_FilterInitStructure.CAN_FilterMaskIdLow=0
// &CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
// &CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
// &/* 全为0,忽略了报文标识符判别 */
// &CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
// &CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
& CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
//FFAx : 过滤器位宽设置 报文在通过了某过滤器的过滤后,
//将被存放到其关联的FIFO中。 0:过滤器被关联到FIFO0; 1:过滤器被关联到FIFO1。
& CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//FACTx : 过滤器激活 软件对某位设置1来激活相应的过滤器。只有对FACTx位清0,
//或对CAN_FMR寄存器的FINIT位设置1后,才能修改相应的过滤器寄存器
//x(CAN_FxR[0:1])。 0:过滤器被禁用; 1:过滤器被激活。
& CAN_FilterInit(&CAN_FilterInitStructure);
& /* CAN FIFO0 接收中断使能 */&
& CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
& /* 发送一帧报文 */
& TxMessage.StdId=0x00;
& TxMessage.ExtId=0x1234;
& TxMessage.IDE=CAN_ID_EXT;
& TxMessage.RTR=CAN_RTR_DATA;
& TxMessage.DLC=2;
& TxMessage.Data[0]=0xDE;
& TxMessage.Data[1]=0xCA;
& CAN_Transmit(CAN1, &TxMessage);
& /* 等待接收成功标志置位 */
& ret = 0xFF; &
& while(ret == 0xFF);
& /* 接收中断禁止*/
& CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);
& return (TestStatus)
/******************* (C) COPYRIGHT 2011 奋斗STM32 *****END OF FILE****/
void USB_LP_CAN1_RX0_IRQHandler(void)
& CanRxMsg RxM
& RxMessage.StdId=0x00;
& RxMessage.ExtId=0x00;
& RxMessage.IDE=0;
& RxMessage.DLC=0;
& RxMessage.FMI=0;
& RxMessage.Data[0]=0x00;
& RxMessage.Data[1]=0x00;
& CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
& /* 比较是否是发送的数据和ID */&
// &if((RxMessage.ExtId==0x1234) && (RxMessage.IDE==CAN_ID_EXT)
// & & && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]&&8)==0xDECA))
& /* 比较报文长度与内容 */&
& if((RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]&&8)==0xDECA))
& & ret = 1;
& & & //接收成功
& & ret = 0;
& //接收失败
注册时间: 10:41
回复数: 49476
主题数: 364
酷贴数:26
论坛积分:53168
来自: 湖南
有两个板子测试没有?
正常模式必须有2个板子测试
我的淘宝小店:
注册时间: 21:31
论坛积分:20
现在,芯片上,都没有波形
注册时间: 10:41
回复数: 49476
主题数: 364
酷贴数:26
论坛积分:53168
来自: 湖南
回复【2楼】&chengxl2010&:
---------------------------------
接2个板子,通信才可能有波形的。
我的淘宝小店:
注册时间: 16:44
论坛积分:14
PA11和PA12作为CAN接口脚为什么还要重映射?把它设为上拉复用输入和推挽输出就是作为CAN总线引脚来使用了,不用重映射的。
你这样初始化把CAN引脚重映射到PB8\PB9去了,又没有初始化PB的GPIO,当然量不到波形。
把GPIO_PinRemapConfig(GPIO_Remap1_CAN1&,&ENABLE);&&&&&//端口复用为CAN1
这一句注释掉再试试,
另外既然不用重映射,RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,&ENABLE);这句也最好注释掉,但注释掉上面那句应该就能看到波形了。
原子站长,不用两个板子,他说的是芯片上,明显是用示波器量的,除非静默回环模式,否则示波器怎么都该在CANTX管脚上看到波形。
注册时间: 17:57
回复数: 28
论坛积分:48
回复【4楼】&翼间&:
---------------------------------
明显不是原子板&&楼上想多了
请选择一个版面...
STM32-F0/F1/F2专区
STM32-F3/F4专区
MSP430专区
ARM7/ARM9/ARM11专区
其他Cortex系列
uCOS & uCGUI & Emwin
trochili(飞鸟)操作系统
中国RTOS联盟
FPGA/CPLD / DSP专区
数字,模拟,高频电路
编程语言学习
蓝牙/WIFI/Zigbee等通信技术
开发工具专栏
UOL 单片机面向对象语言
DIY大赛专区
DIY项目资料专区
论坛建设区
二手交易专栏
& 开源电子网() |

我要回帖

更多关于 stm32 读保护 的文章

 

随机推荐