|
http://www.eefocus.com/bbs/article_244_380394.html
http://www.stmcu.org/bbs/article_244_380402.html
下面是从控器部分代码:
main.c部分代码
/******************** (C) COPYRIGHT *******************************************
* File Name : main.c
* Author : MJQ
* Version : V1.0
* 环境 : mdk423-固件库V3.5版本、
* 芯片 : STM32F103VB-ALIENTEK开发板
* Date : 2012-04-12
* Description : 外部中断函数,按key0 led1灭串口发送0xaa、按key1 led2灭串口发送0x55、
接收到电脑发送数据或按PA0时,led1、led2全亮
* 定义 : LED1-------PA8
LED2-------PD2
KEY0-------PA13
KEY1-------PA15
TXD1-------PA9
RXD1-------PA10
EXTI0------PA0
********************************************************************************/
/*---------------------Includes------------------------------------------------*/
#include "stm32f10x.h"
#include "misc.h"
#include "led.h"
#include "key.h"
#include "usart.h"
//#include "exti.h"
#include "can.h"
void RCC_Configuration(void);
void Delay(__IO uint32_t nCount);
//___________________Global Variable declare________
u8 CAN_TransmitDataBuf[8];
u8 ADC_num=0;
u16 ADC_Data0[10];
u16 ADC_Data1[10];
u16 ADC_Data2[10];
u16 ADC_Data3[10];
//______________________________________________
//___________________________ADC modue__________
void Adc_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog输入
//通道10/11设置
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
RCC->CFGR&=~(3<<14); //分频因子清零
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降!
RCC->CFGR|=2<<14;
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16; //独立工作模式
ADC1->CR1&=~(1<<8); //非扫描模式
ADC1->CR2&=~(1<<1); //单次转换模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!!必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1&=0<<20;
//设置通道0~3的采样时间
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采样时间清空
ADC1->SMPR2|=7<<9; //通道3 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<6; //通道2 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<0; //通道0 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
//该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置转换序列
ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch
ADC1->SQR3|=ch;
ADC1->CR2|=1<<22; //启动规则转换通道
while(!(ADC1->SR&1<<1));//等待转换结束
return ADC1->DR;//返回adc值
}
//_________________________________________________
//_____________________ADC 采样值发送________
void ADC_TransmitByCan(u16 Data_CH1,u16 Data_CH2,u16 Data_CH3)
{
}
//
//int i=0;
u32 GetP(u16 *ADC_Point)
{
u32 ADC_sum=0;
u16 Max=0;
u16 Min=0xFF;
u8 index=0;
for(index=0;index<9;index++)
{
if( (*(ADC_Point+index)) >Max )
{
Max=(*(ADC_Point+index));
}
if( (*(ADC_Point+index)) <Min)
{
Min=(*(ADC_Point+index));
}
ADC_sum+=(u32) ((*(ADC_Point+index)));
}
ADC_sum=(ADC_sum-Max-Min)/8;
return ADC_sum;
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)
{
u32 ADC0_sum=0;
u32 ADC1_sum=0;
u32 ADC2_sum=0;
if(TIM3->SR&0X0001)//溢出中断
{
ADC_Data1[ADC_num]=Get_Adc(ADC_Channel_1);
ADC_Data2[ADC_num]=Get_Adc(ADC_Channel_2);
ADC_Data0[ADC_num]=Get_Adc(ADC_Channel_0);
ADC_num++;
if (ADC_num>=10)
{
ADC0_sum=GetP(ADC_Data0);
ADC1_sum=GetP(ADC_Data1);
ADC2_sum=GetP(ADC_Data2);
CAN_TransmitDataBuf[1]=(ADC0_sum&0x00ff);
CAN_TransmitDataBuf[0]=((ADC0_sum>>8)&0x00ff);
CAN_TransmitDataBuf[3]=(ADC1_sum&0x00ff);
CAN_TransmitDataBuf[2]=((ADC1_sum>>8)&0x00ff);
CAN_TransmitDataBuf[5]=(ADC2_sum&0x00ff);
CAN_TransmitDataBuf[4]=((ADC2_sum>>8)&0x00ff);
CAN_TransmitData(6,CAN_TransmitDataBuf,0xAAAA);
}
}
TIM3->SR&=~(1<<0);//清除中断标志位
}
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void Timer_init(u16 arr,u16 psc)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC->APB1ENR|=1<<1;//TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms
TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟
//这两个东东要同时设置才可以使用中断
TIM3->DIER|=1<<0; //允许更新中断
TIM3->DIER|=1<<6; //允许触发中断
TIM3->CR1|=0x01; //使能定时器3
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //设置串口中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//_______________________________________________
int main(void)
{
RCC_Configuration(); //系统时钟配置
//LED_GPIO_Config(); //led配置
KEY_GPIO_Config(); //按键配置
//USART_Init_Config(); //串口配置
// EXTI_Init_Config();
Adc_Init();
CAN_Init_Config();
Timer_init(50,6400);
while (1)
{
LED1_ON;
LED2_ON;
Delay(0xFFFFF);
Delay(0xFFFFF);
}
}
void RCC_Configuration(void)
{
/* Setup the microcontroller system. Initialize the Embedded Flash Interface,
initialize the PLL and update the SystemFrequency variable. */
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB,ENABLE); //打开重映射时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* GPIOA clock enable */
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* GPIOB clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* CAN Periph clock enable */
}
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(uint8_t* file, uint32_t 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)
{
}
}
#endif
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
CAN 部分代码
#include "can.h"