C8051F040的SPI程序2
C8051F040的SMBus程序2
unsigned char SMB_DATA_OUT;
unsigned char TARGET; bit SMB_BUSY;
bit SMB_RW;
unsigned long NUM_ERRORS; // 16-bit SFR declarations sfr16 RCAP4 = 0xCA; sfr16 TMR4 = 0xCC; sbit LED = P1^6; sbit SDA = P0^0; sbit SCL = P0^1;
#define SMB_MTARBLOST 0x38 #define SMB_MRADDACK 0x40 #define SMB_MRADDNACK 0x48 #define SMB_MRDBACK #define SMB_MRDBNACK 0x50 0x58
//----------------------------------------------------------------------------// Global VARIABLES //----------------------------------------------------------------------------unsigned char SMB_DATA_IN; // Global holder for SMBus data // All receive data is written here // Global holder for SMBus data. // All transmit data is read from here // Target SMBus slave address // Software flag to indicate when the // SMB_Read() or SMB_Write() functions // have claimed the SMBus // Software flag to indicate the // direction of the current transfer // Counter for the number of errors.
C8051F040开发系统板使用说明书
第一章 C8051F040开发系统板简介1.1 开发系统的组成Cygnal C8051F040单片机开发系统主要由Cygnal 片上系统单片机开发工具、C8051F040片上系统单片机和系统实验板三部分组成,应用该系统可进行片上系统单片机较典型应用的实验,请参见以下介绍。
1.2 Cygnal C8051F单片机开发工具简介1.2.1 开发工具概述Cygnal 的开发工具实质上就是计算机IDE 调试环境软件及计算机RS-232到C8051F单片机JTAG口的协议转换器(EC2-N1)的组合。
Cygnal C8051F系列所有的单片机片内均设计有调试电路该调试电路通过边界扫描方式获取单片机片内信息,通过10线的JTAG接口与开发工具连接以便于进行对单片机在片编程调试。
该开发系统板中的核心部分是Cygnal C8051F040单片机。
适配器(EC2-N1)一端与计算机相连,另一端与C8051F单片机的JTAG口相连,应用Cygnal 提供的IDE调试环境就可以进行非侵入式、全速的在系统编程(ISP)和调试。
Cygnal 开发工具支持观察和修改存储器和寄存器支持断点、观察点、堆栈指示器、单步、运行和停止命令。
调试时不需要额外的目标RAM、程序存储器、定时器或通信通道,并且所有的模拟和数字外设都正常工作。
1.2.2 开发工具主要技术指标●支持的目标系统:所有C8051Fxxx 系列单片机;●系统时钟:最大可达25MHz;●通过RS232接口与PC机连接;●支持汇编语言和C51源代码级调试;●第三方工具支持Keil C。
1.2.3 IDE 软件运行环境要求PC机能够运行开发工具软件并能与串行适配器通信。
对PC机有如下系统要求:●Windows 95/98/Me/NT/2000/XP 操作系统;●32MB RAM;●40MB 自由硬盘空间;●空闲的COM 口。
1.2.4 开发工具与PC 机硬件连接硬件连接及软件安装:●将JTAG 扁平电缆与串行示配器EC2 连接●将JTAG 扁平电缆的另一端与目标系统连接●将RS232 串行电缆的一端与EC2 连接●连接RS232 串行电缆的另一端到PC●给目标系统上电●插入CD 并运行SETUP.EXE 将IDE 软件安装到您的PC 机●在PC 机的开始菜单的程序项中选择Cygnal IDE 点击Cygnal 图标运行IDE软件。
C8051F040的晶振程序2
// F04x_Oscillator_CMOS.c//----------------------------------------------------------------------------- // Copyright 2006 Silicon Laboratories, Inc.// //// Program Description://// This example demonstrates how to initialize for and switch to an external// CMOS Oscillator.// - Pinout:// P0.0 -> /SYSCLK//// P1.6 -> LED//// all other port pins unused//// XTAL1 -> XTAL1 - External CMOS Oscillator input////// How To Test://// 1) Define the input CMOS clock frequency using <CMOS_clock>// 2) Compile and download code to a 'F04x device.// 3) Connect the CMOS input clock to XTAL1 (J21 on the TB)// 4) Run the code:// - the test will blink an LED at a frequency based on the CMOS// Oscillator// - the 'F04x will also output the SYSCLK to a port pin (P0.0) for// observation////// FID: 04X000010// Target: C8051F04x// Tool chain: Keil C51 7.50 / Keil EVAL C51// Command Line: None//// Release 1.0// -Initial Revision (TP)// -31 MAY 2006////----------------------------------------------------------------------------- // Includes#include<C8051F040.h>// SFR declarations//----------------------------------------------------------------------------- // Global CONSTANTS//----------------------------------------------------------------------------- #define CMOS_clock 308990 // CMOS oscillator frequency// Timer2 using SYSCLK/12 as its time base// Timer2 counts 65536 SYSCLKs per Timer2 interrupt// LED target flash rate = 10 Hz (may be slower, depending on CMOS_clock)//// If CMOS_clock is too slow to divide into a number of counts,// <count> will always remain 0. In this case, the LED Flash rate will be// slower than 10 Hz.#define LED_interrupt_count CMOS_clock/12/65536/10sfr16 RCAP2 = 0xCA; // Timer2 reload valuesfr16 TMR2 = 0xCC; // Timer2 countersbit LED = P1^6; // LED='1' means ON//----------------------------------------------------------------------------- // Function PROTOTYPES//-----------------------------------------------------------------------------void SYSCLK_Init (void);void ExtCMOSOsc_Init (void);void Port_Init (void);void Timer2_Init (void);void Timer2_ISR (void);//----------------------------------------------------------------------------- // MAIN Routine//----------------------------------------------------------------------------- //// Main routine performs all configuration tasks, switches to the external CMOS // oscillator, and loops forever, blinking the LED.//void main (void) {WDTCN = 0xDE; // disable watchdog timerWDTCN = 0xAD;SFRPAGE = CONFIG_PAGE;SYSCLK_Init (); // Initialize system clock to 24.5MHzExtCMOSOsc_Init (); // Initialize for and switch to the// external CMOS oscillatorPort_Init (); // Initialize crossbar and GPIOSFRPAGE = TMR2_PAGE;Timer2_Init (); // Init Timer2 to generate// interrupts for the LED.EA = 1; // Enable global interruptsSFRPAGE = LEGACY_PAGE; // Sit in this SFRPAGEwhile (1) { // Spin forever}}//----------------------------------------------------------------------------- // Initialization Routines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // SYSCLK_Init ()//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This routine initializes the system clock to use the internal 24.5 MHz// oscillator as its clock source. Also enables missing clock detector reset. //void SYSCLK_Init (void){OSCICN = 0x83; // Configure internal oscillator for// its highest frequency (24.5 MHz)RSTSRC = 0x04; // Enable missing clock detector}//----------------------------------------------------------------------------- // ExtCMOSOsc_Init ()//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This routine initializes for and switches to the External CMOS Oscillator. //// Note: In CMOS clock configuration, the clock source should be wired to the // XTAL1 pin as shown in Option 4 in the Oscillators section of the datasheet. //void ExtCMOSOsc_Init (void){OSCXCN = 0x20; // External Oscillator is a CMOS clock// (no divide by 2 stage)// XFCN bit settings do not apply to a// CMOS clockCLKSEL = 0x01; // Switch to the external CMOS clock}//----------------------------------------------------------------------------- // Port_Init ()//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// Configure the Crossbar and GPIO ports.//// P0.0 digital push-pull /SYSCLK// P0.1 unused// P0.2 unused// P0.3 unused// P0.4 unused// P0.5 unused// P0.6 unused// P0.7 unused//// P1.0 unused// P1.1 unused// P1.2 unused// P1.3 unused// P1.4 unused// P1.5 unused// P1.6 digital push-pull LED// P1.7 unused//// P2 unused//// P3 unused//// P4 unused//// P5 unused//// P6 unused//// P7 unused//void PORT_Init (void){P0MDOUT |= 0x01; // Enable /SYSCLK as a push-pull output P1MDOUT |= 0x40; // Enable LED as a push-pull outputXBR1 = 0x80; // Route /SYSCLK to a port pinXBR2 = 0x40; // Enable crossbar and weak pull-ups}//----------------------------------------------------------------------------- // Timer2_Init ()//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// Configure Timer2 to 16-bit auto-reload and generate an interrupt after the // maximum possible time (TMR2RL = 0x0000).//void Timer2_Init (void){TMR2CN = 0x00; // Stop Timer2; Clear TF2;// auto-reload modeTMR2CF = 0x00; // use SYSCLK/12 as timebase; count upRCAP2 = 0x0000; // Init reload valueTMR2 = 0xffff; // Set to reload immediatelyET2 = 1; // Enable Timer2 interruptsTR2 = 1; // Start Timer2}//----------------------------------------------------------------------------- // Interrupt Service Routines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // Timer2_ISR//----------------------------------------------------------------------------- //// This routine changes the state of the LED whenever Timer2 overflows.//void Timer2_ISR (void) interrupt 5{static unsigned int count = 0;TF2 = 0; // Clear Timer2 interrupt flagif (count == LED_interrupt_count){LED = ~LED; // Change state of LEDcount = 0;}else{count++;}}//----------------------------------------------------------------------------- // End Of File//-----------------------------------------------------------------------------。
C8051F040的UART程序2
OSCICN = 0x80;
// Set internal oscillator to run // at its slowest frequency // Select the internal osc. as // the SYSTEMCLOCK source
CLKSEL = 0x00;
// Initialize external crystal oscillator to use 22.1184 MHz crystal OSCXCN = 0x67; for (i=0; i < 256; i++); while (!(OSCXCN & 0x80)); // Enable external crystal osc. // Wait at least 1ms // Wait for crystal osc to settle
sfr16 RCAP2 sfr16 TMR2
= 0xCA; = 0xCC;
// Timer2 capture/reload // Timer2
//----------------------------------------------------------------------------// Global Constants //----------------------------------------------------------------------------#define BAUDRATE 115200 // Baud rate of UART in bps
//----------------------------------------------------------------------------// Includes //----------------------------------------------------------------------------#include <C8051F040.h> #include <stdio.h> // SFR declarations
C8051F040中CAN控制器的应用
摘要:介绍C8051F040单片机内部CAN控制器的应用。
详细叙述此控制器的构成及其访问方式,指出在使用时是如何配置控制器的相关控制寄存器,并且给出CAN控制器在应用中的物理层硬件电路和应用层软件设计。
单片机与CAN总线连接的传统方式是将CPU与总线控制器和总线收发器相连后再接入总线网络,这样使CPU外围电路复杂化,整个系统受外部影响较大。
为了解决这一问题,很多单片机厂商纷纷将CAN控制器集成在单片机芯片上。
目前,单片机内部集成的CAN控制器有Motorola公司的MC68HC912DG128A、Philips公司的P87C591、Atmel公司的AT89C51CC01和A T89C51CC02、Intel公司的TN87C196CA和TN87C196CB以及Cygnal 公司的C8051F040等。
不同单片机内部CAN控制器的使用方法有所不同,但存在着很多相似之处。
这里以C8051F040为列详细介绍其内部CAN控制器的使用方法,希望通过这篇文章能给初学带来方便,并能和广大的单片机爱好者就这一问题做进一步的讨论。
1 C8051F040 CAN控制器构成及访问方式C8051F040单片机是美国Cygnal公司生产的完全集成的混合信号系统级芯SoC(System on Chip),具有与8051指令集完全兼容的CIP-51内核。
它在一块芯片上集成了构成一个单片机数据采样或控制系统所需要的几乎所有模拟和数字外设及其它功能部件。
它具有64KB Flash、4352B RAM、CAN控制器2.0、2个串行接口、5个16位定时器、12位A/D转换器、8位A/D转换器及12位D/A转换器等,它内部还带有JTAG接口,使调试变得非常方便。
C8051F040内部集成的CAN控制器为Bosch CAN控制器。
此CAN控制器有以下几部分构成:CAN内核、报文RAM(与C8051 RAM相互独立)、报文处理状态机制和CAN控制寄存器在CAN控制器里只有三个寄存器可通过CIP-51中的特殊功能寄存器直接访问,其它的寄存器只能通过CAN0ADR、CAN0DATH和CAN0DATL寄存器以地址索引的方式间接访问。
C8051F040_内部温度传感器C程序
C8051F040_内部温度传感器C程序附录一://内部温度传感器调试程序////利用过采样实现16位精度////ADC0_TEMP_PRO.c#include#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=tem ppage #define STACK_LEN 128//采样128次,再将128个数据总和除以8//处理后的数据相当于16个原始数据之和,在数值表现形式上为16bittypedef unsigned int uint;typedef unsigned char uchar;typedef unsigned long ulong;sfr16 RCAP2=0xca;sfr16 RCAP3=0xca;sfr16 RCAP4=0xca;sfr16 TMR4=0xcc;sfr16 TMR3=0xcc;sfr16 TMR2=0xcc;sfr16 PCA0CP0=0xfb;sfr16 PCA0CP1=0xfd;sfr16 PCA0CP2=0xe9;sfr16 PCA0CP3=0xeb;sfr16 PCA0CP4=0xed;sfr16 PCA0CP5=0xe1;sfr16 ADC0VAL=0xbe;sfr16 ADC0GT=0xc4;sfr16 ADC0LT=0xc6;uchar temppage;bit isnewdata;uint kk;float temp;uchar stack_index;ulong total;xdata float t[20];//存放温度检测数据,为20个数据xdata uint mystack[STACK_LEN];//过采样数据数组void adc0_mux(uchar type,uchar source);void adc0_source(uchar source);void p3anolog_ini(uchar port);void HVDA_ini(uchar gaind);void adc0_ini();void delay1ms(uint time);void config();void adc0_mux(uchar type,uchar source){//type 配置测量方式为差动还是单端输入//source 为ADC0通道选择(共有9个通道)SFRPAGE=0x00;AMX0CF=type;AMX0SL=source;}void adc0_source(uchar source){//ADC0通道选择,为adc0_mux()的简化函数SFRPAGE=0x00;AMX0SL=source;}void p3anolog_ini(uchar port){//配置p3口模拟输入管脚SFRPAGE=0x00;AMX0PRT=port;SFRPAGE=0x0f;P3MDIN&=~port;//将相应管脚配置成模拟输入口}void HVDA_ini(uchar gaind){//高压差动放大器配置SFRPAGE=0x00;HVA0CN=gaind;}void adc0_ini(){SFRPAGE=0x00;ADC0CF=0x80;//ADC0时钟为系统时钟17分频,PGA增益为1 ADC0CN=0x80;/*AD0EN=1,ADC0模块使能AD0TM=0,ADC0为连续跟踪模式AD0CM1:AD0CM0=00b,为AD0BUSY启动方式AD0LJST=0,数据存储格式右对齐,即ADC0H存放12bit高四位*/REF0CN&=0x0f;//AD0VRS=0,ADC0参考电压为VREFAREF0CN|=0x07;//TEMPE=1,内部温度传感器工作/*BIASE=1,偏移产生器工作REFBE=1,内部参考电平工作,电路部分须将VREF参考输出(C8051F40的第12管脚)与VREF0(C8051F040的16管脚相连,并最好并联一个4.7uF和0.1uF的旁路电容以电平滤波*/adc0_source(9);//选择第9通道,即选择温度信号为AD转换EIE2 |= 0x02; //开ADC0中断}void delay1ms(uint time){//延迟1msuint i;uint j;for (i=0;i<time;i++){< bdsfid="147" p=""></time;i++){<> for(j=0;j<300;j++);}}void config(){//crossbar 使能,但并没有进行外围设备配置WDTCN = 0x07; // Watchdog Timer Control RegisterWDTCN = 0xDE; // Disable WDTWDTCN = 0xAD;SFRPAGE = 0x0F;XBR0 = 0x00; // XBAR0: Initial Reset ValueXBR1 = 0x00; // XBAR1: Initial Reset ValueXBR2 = 0x40; // crossbar使能与否并不影响此程序运行XBR3 = 0x00; // XBAR3: Initial Reset ValueSFRPAGE = 0x0F;P0MDOUT = 0x00; // Output configuration for P0P1MDOUT = 0x00; // Output configuration for P1P2MDOUT = 0x00; // Output configuration for P2P3MDOUT = 0x00; // Output configuration for P3P4MDOUT = 0x00; // Output configuration for P4P5MDOUT = 0x00; // Output configuration for P5P6MDOUT = 0x00; // Output configuration for P6P7MDOUT = 0x00; // Output configuration for P7P1MDIN = 0xFF; // Input configuration for P1P2MDIN = 0xFF; // Input configuration for P2P3MDIN = 0xFF; // Input configuration for P3SFRPAGE = 0x0F;CLKSEL = 0x00; // Oscillator Clock SelectorOSCXCN = 0x00; // EXTERNAL Oscillator Control Register OSCICN = 0x84; // Internal Oscillator Control Register } void main(){char i;config();adc0_ini();//ADC0初始化ADC0START;//ADC0启动EA=1;i=0;stack_index=0;while(1){if(isnewdata){//由该位查询ADC0转化值是否更新if(stack_index==STACK_LEN)for(i=0,total=0;i<stack_len;i++)< bdsfid="187" p=""></stack_len;i++)<>total+=stack[i];total/=8;//此时total的值即为16bit精度采样值temp=(float)total/65536.0;temp*=2.43;temp-=0.776;temp/=0.00286;//将测量值转化成真实温度值isnewdata=0;t[i]=temp;//将温度检测值存入长度为20的数组中i++;if(i>19)i=0;//在此设断点,观察程序运行结果delay1ms(100);ADC0START;}}}void ADC0_ISR() interrupt 15{//ADC0中断SFRPAGE=0x00;AD0INT=0;isnewdata=1;if(stack_index>=STACK_LEN)//STACK_LEN需小于等于256,否则stack_index要定义成uint型数据stack_index=0;stack[stack_index]=ADC0VAL;stack_index++;}(注:本资料素材和资料部分来自网络,仅供参考。
C8051F系列单片机串口通讯程序
C8051F系列单片机串口通讯程序C8051F系列单片机串口通讯程序采用C8051F020单片机//串口编程--接收PC发过来的字符串,回发字符串.发送期间中断控制LED灯闪烁//采用外部晶振22.1184MHz 使用定时器1,方式2产生波特率,SMOD = 0或者 1 //定时器初值X=256-SYSCLK*(SMOD+1)/(BAUDRATE*384)/#includesfr16 TMR3RL = 0x92; //定时器3重装载寄存器sfr16 TMR3 = 0x94; //定时器3计数器#define uchar unsigned char#define uint unsigned int//----------------------------------------------------------------------//参数设置区//----------------------------------------------------------------------#define BAUDRATE 4800 //波特率bps#define CLKOUT 22118400 //外部晶振,修改也要修改OSCXCN #define SMODVAL 0 //SMOD的值,修改请也修改PCONVAL#define PCONVAL 0x00 //PCON的值,=0x00时SMOD0=0; =0x80时SMOD0=1 #define TXVAL (256-CLKOUT*(SMODVAL+1)/BAUDRATE/384) //定时器初值#define MAX_LEN 10 //每次接收/发送字符串的长度//---------------------------------------------------------------------//全局变量//---------------------------------------------------------------------sbit LED = P1^6; //LED '1'亮'0'灭bit readFlag = 0; //读标志uchar readCounts = 0; //已经读取的字符个数,与MAX_LEN比较uchar idata trdata[MAX_LEN]; //要接收/发送的字符串//----------------------------------------------------------------------//子函数声明//---------------------------------------------------------------------- void SYSCLK_Init(void); //系统时钟初始化void PORT_Init(void); //端口初始化void UART0_Init(void); //串口UART0初始化void Send_Char(uchar ch); //发送单个字符void Send_String(uchar * str, uint len); //发送一个字符串void UART0_ISR(); //串口中断服务程序,接收字符void Timer3_Init(uint counts); //定时器3初始化void Timer3_ISR(void); //定时器3中断服务程序//---------------------------------------------------------------------- //主函数//---------------------------------------------------------------------- void main(void){WDTCN = 0xde; //禁止看门狗WDTCN = 0xad;SYSCLK_Init(); //时钟初始化PORT_Init(); //端口初始化UART0_Init(); //串口初始化Timer3_Init(CLKOUT/12/10); //定时器初始化EA = 1; //开全局中断while(1){if(readFlag) //已经读取{readFlag = 0; //清零Send_String(trdata,MAX_LEN); //发送字符串}}}//----------------------------------------------------------------------//子函数具体实现//----------------------------------------------------------------------//系统时钟初始化void SYSCLK_Init(void){uint i;OSCXCN = 0x67; //采用外部晶振22.1184MHz,不分频. 选型OSCXCN=0110,0111 for(i=0;i<256;i++); //等待>1mswhile(!(OSCXCN&0x80)); //查询直到XTLVLD=1,晶振稳定OSCICN = 0x88; //切换到外部振荡器,允许时钟失效监测器. OSCICN=1000,1000 }//端口初始化void PORT_Init(void){XBR0 = 0x04; //允许UART0,RX,TX连到2个端口引脚. XBR0=0000,0100XBR1 = 0x00;XBR2 = 0x40; //交*开关使能P0MDOUT |= 0x03; //P0.0为推拉方式输出,即TX0,RX0所在的端口0000,0011P1MDOUT |=0x40; //P1.6为推拉方式输出,即LED所在的端口0100,0000}//串口初始化void UART0_Init(void){SCON0 = 0x50; //选择串口方式1,波特率可变SCON0=0101,0000TMOD = 0x20; //选择T1,方式2,自动再装入8位计数器TH1 = (int)TXVAL; //T1初值,根据波特率,时钟等计算. 0xF4, bps=4800bpsTL1 = (int)TXVAL;ES0 = 1; //UART0中断开启TR1 = 1; //启动定时器T1PCON |= PCONVAL; //PCON=0x00,SMOD = 0 ; PCON=0x80,SMOD=1 TI0 = 1; //声明TX0就绪,可以发送TR0 = 1;}//定时器初始化void Timer3_Init(uint counts){TMR3CN = 0x00; //禁止定时器T3,清TF3,采用SYSCLK/12为时基TMR3RL = -counts; //初始化重装载值TMR3 = 0xffff; //设置为立即重装载EIE2 |= 0x01; //T3中断开启TMR3CN |= 0x04; //启动T3}//发送单个字符void Send_Char(uchar ch){SBUF0 = ch; //送入缓冲区while(TI0 == 0); //等待发送完毕TI0 = 0; //软件清零}//发送字符串,调用Send_Char() len字符串长度void Send_String(uchar * str,uint len){uint k = 0;do{Send_Char(*(str + k));k++;} while(k < len);}//定时器3中断服务程序void Timer3_ISR(void) interrupt 14 using 0 {TMR3CN &= ~(0x80); //清TF3LED = ~LED;}//UART0中断服务程序. 接收字符void UART0_ISR(void) interrupt 4 using 1 {uchar rxch;if(RI0) //中断标志RI0=1 数据完整接收{RI0 = 0; //软件清零rxch = SBUF0; //读缓冲if(readCounts>=MAX_LEN){readCounts = 0;readFlag = 1;}trdata[readCounts] = rxch; //存入数组,供发送readCounts++;}}//------------------------------------------------------------- //程序结束。
C8051F040的Timer程序2
//-----------------------------------------------------------------------------
// Timer0_Init
// 3) To change the speed of the SIGNAL waveform, modify
// SOFTWARE_DELAY
// 4) Compile the project
// 5) Download code to a 'F04x device
// 6) Verify J1 and J3 are populated on the 'F04x TB.
// to enable the counting process (GTE).
//
// This code uses the 'F040DK as HW platform.
//
//
// Pinout:
// P0.0 -> T0 (Timer0 External Input)
// P0.1 -> /INT0
LED = 0; EA = 1;
// Enable global interrupts
while (1) {
if (BUTTON == 0) {
GTE = 1; } eΒιβλιοθήκη se {GTE = 0; }
// If button pressed, enable counting
// Wait a certain time before toggling signal for (counter=0; counter < SOFTWARE_DELAY; counter++);
C8051F040的车用CAN总线智能节点设计
C8051F040的车用CAN总线智能节点设计电气与电子系统是车辆的重要组成部分,其工作状态直接影响车辆的性能。
按照传统设计思想设计车辆电气系统时,往往采取堆积各种子系统的途径来提高系统的性能,因此车辆内部各子系统之间单纯面向任务而不考虑与全局的关系。
随着子系统及装置数量不断增加,传统设计方法遇到了一系列问题:线路增多、布线复杂、电磁干扰增加、系统可靠性下降、检查维修困难等。
为了解决上述问题,现代车辆采用了综合电子系统。
总线是综合电子系统的基础,通过总线节点,综合电子系统可采集、使用、分配和共享车内所有电子系统的各种信息,达到弱化矛盾、增强整体功能的目的。
CAN 总线由于具有性价比高、可靠性高、实时性好、灵活性强等特点,得到广泛应用。
本文针对CAN 总线,提出了一种基于C8051F040 的通用总线智能节点的设计方法。
1 总体设计本文采用C8051F040 单片机作为智能节点的主控芯片来设计CAN 总线通用智能节点。
智能节点通过现场信号调整、高速数据采集获取该节点下设备的参数,并通过总线收发器将数据发送到CAN 总线,同时根据参数及总线上的其他信息和命令对设备进行控制。
通过CAN 总线智能节点,可将车辆电气系统各子系统及设备紧密联系在一起,构成一个实时控制网络,如图1 所示。
考虑到智能节点的通用性,经过对车辆各子系统和设备参数进行分析,确定了智能节点主要指标。
①信号输入:8 路模拟信号输入,16 路数字信号输入,2 路脉冲量输入;②控制信号输出:2 路模拟控制信号输出,8 路数字信号输出;③CAN 总线接口:1 个CAN 总线接口(支持CAN2.0A 和CAN2.0B)。
2 硬件设计CAN 总线节点有两种设计方法,一种采用通用微控制器结合独立CAN 控制器加上收发器,另一种采用集成CAN 控制器的微控制。
C8051F040的看门狗程序
// 2) Verify J1 and J3 are connected (LED and SW jumpers).
// 3) Run the code:
//
- The test will reset the WDT and blink an LED until the switch (SW)
//
is pressed, simulating an external stimulus.
// Reset the WDT
// Initialize crossbar and GPIO // Wait for the switch (SW) to be // released before continuing // Reset the WDT
// Inititialize the Watchdog timeout // interval
//
- When the WDT trips, it will cause a reset. The code checks for a
//
WDT reset and will disable the WDT and blink the LED twice as fast
//
to indicate the current state.
// Init Timer0 to periodically reset // the WDT
SFRPAGE = TMR2_PAGE; Timer2_Init ();
EA = 1;
// Init Timer2 to generate // interrupts for the LED.
// Enable global interrupts
C8051F410例程简介
ADC 2个IDAC 1个外部中断Interrupts 1个PCA(可编程计数器阵列)6个PortIO 1个定时器Timer 7个UART 2个Watchdog 1个Oscillators 6个Comparators 1个SMBus 6个SPI 3个ADC例1:单通道输入程序描述:ADC0对P1.1端口输入电压采样2048次,累加后,求平均;结果通过UART输出,到电脑,串口调试程序,接收,显示。
ADC例2:多通道输入程序描述:使用ADC0内部多路选择器,逐个循环采样6个输入端口电压,并输出到电脑显示。
IDAC例:程序描述:使用IDAC输出一个正弦波。
Interrupts例:程序描述:配置外部中断INT0或INT1作为中断源,按键触发中断,执行中断程序(P0.0电平改变,连接在P0.0的LED亮灭)。
PCA例1:8位输出模式PWM波程序描述:利用PCA8位输出模式,输出PWM波。
PCA例2:16位输出模式PWM波程序描述:利用PCA16位输出模式,输出PWM波。
PCA例3:捕获模式程序描述:利用PCA捕获模式,测量输入引脚事件发生时间。
PCA例4:频率输出模式程序描述:利用PCA频率输出模式,产生一个方波,输出到端口。
PCA例5:高速输出模式(?)程序描述:利用PCA高速输出模式,产生一个方波,输出到端口。
PCA例6:软件定时器模式程序描述:利用PCA软件定时器模式,产生定时的中断;中断程序中,触发LED闪耀。
PortIO例1:端口匹配程序描述:配置端口匹配事件作为中断源,程序执行;当按键时,端口匹配事件触发中断,执行中断程序(触发LED亮)。
PortIO例2:数字输入/输出程序描述:演示怎样设置数字输入/输出方式;两个按键和两个LED分别连接到端口;程序持续检测按键,如果按键按下,则点亮下相应的LED。
Timer例1: 8位重载方式程序描述:演示如何使用定时器0的8位定时计数重载方式;利用定时器0在一定频率下产生一个中断,并且,当用户的中断计数到达选择值时,LED被触发。
C8051F040中文数据手册---精品管理资料
1。
系统概论C8051 F04X 系列单片机是集成在一块芯片上的混合信号系统级单片机,分64个I/O端口管脚(如C8051F040/2)或者32个I/O端口管脚(如C8051F041/3)两类,同时有一个CAN2。
0B 集成控制器。
其最突出的特征见下表,涉及的主要设备特征在1。
1中详解。
25MIPS高速流水线式CIP-51控制器内核. CAN2。
0B 控制对应的有32个信息对象,且每一个都有它自己的屏蔽位。
在系统,全速,非插入式调试接口。
有12位的ADC(C8051F040/1)或10位的ADC(C8051F042/3),带有PGA和模拟复用开关。
对于12位的ADC(峰峰值为60伏)的高压差分放大输入可通过编程得到。
有8位的多通道DAC,带有PGA和模拟复用开关. 有两个12位DAC,通过编程更新时序。
64KB的可编程FLASH存储器. RAM可存储4352(4096+256)字节。
外部内存接口可寻址64K字节. SPI,SMBus/I2C和(2)UART串行接口通过硬件实现。
5个16位通用定时器。
可编程计数/定时阵列有6个捕捉/比较模块. 片内有看门狗定时器,VDD监视器,温度传感器由于有片内VDD监视器,看门狗定时器和时钟震荡器,C8051F04X系列单片机称得上是真正独立的片上系统。
通过使用软件可以用程序很好的管理模拟和数字外设FLASH存储器甚至还有在系统重新编程能力,可提供非易失数据存储,并允许现场更新8051程序。
片内JTAG调试支持功能允许对安装在最终应用系统上的单片机进行非侵入失式(不占用片内资源),全速在系统调试.该调试系统支持和修改存储器和寄存器,支持断点,观察点,单步及运行和停机命令。
在使用JTAG调试时所有的模拟和数字外设都可全功能运行。
每个单片机都可在工业温度范围—45—+85℃内采用2。
7伏到3.6V 的工作电压,端口I/O,/RST和JTAM引脚允许5V的输入信号电压.C8051F040/2为100脚封装,C8051F041/3为64脚TQFP封装(原理框图见图1。
C8051对SPI接口的模拟
关于模拟SPI接口SPI:Serial Peripheral InterfaceSPI接口由四个通道组成:片选信号通道(CS),时序信号通道(SCLK),数据输入通道(Din),数据输出通道(Dout)组成。
通道名在不同器件中可能不同,且部分器件的SPI接口中会缺少Dout通道,但其实际应用依然参照SPI的基本时序。
模拟SPI接口就是模拟其工作时序,数据在SCLK上升沿被MCU写入,在下降沿被MCU读取。
其余按DATASHEET描述编写。
例子:模拟X5045 SPI写时序:/*****************************************************函数原型:void writeMemoryArrayclock_SPI(unsigned char clock)功能:模拟SPI写时序。
******************************************************void writeMemoryArrayclock_SPI(unsigned char dat){int i;for (i=8;i>0;i--) //数据循环8次{if (dat & 0x80)x5045_SI = 1;elsex5045_SI = 0; //数据锁存在SI线内nNop(5);x5045_SCK = 0;nNop(5);x5045_SCK = 1; //上升沿数据输入dat= dat << 1; //数据左移一位}x5045_SI = 0;nNop(5);x5045_SCK = 0;}例子:模拟X5045 SPI读时序/*************************************************************** 函数原型:void readMemoryArrayclock_SPI(unsigned char dat)功能:模拟SPI读时序。
C8051系列常见问题
振荡器问:内部时钟振荡器是否稳定?是否可以用于产生波特率的时基?答:不同器件的内部时钟振荡器的精度是不同的(±20%)。
随电源电压变化,它也将发生变化(6.5%/V)。
但基本不随温度变化(<1%温度变化范围-40℃~+85℃)。
由于不同器件内部振荡器的离散性较大,所以不能用于产生波特率,应该外接标准晶体。
而有些器件,如C8051F3xx/f12x/f04x/f06x内部振荡器精度为±2%,可用于产生波特率。
问:片内/外振荡器如何配置?答:正确步骤:1、允许外部振荡器;2、等待1ms;3、查询XTLVLD '0'->'1'4、切换到外部振荡器。
注意:振荡器频率的选择,即OSCXCN寄存器的配置(外部振荡器频率控制位的设置)。
问:使用外部晶振应注意哪些问题?答:1、所有的模拟和数字电源引脚都应接电源(2.7~3.6V);2、C8051F3xx系列器件的晶振引脚间应跨接一个10M电阻(在新华龙网站的“主页”—“原理图/PCB库”中有C8051F系列单片机的典型接线图);3、晶振、电容等相关器件尽量靠近单片机的晶振引脚。
问:系统时钟切换到外部时钟后,内部的时钟是否应关闭?答: 可以选择关闭或不关闭,但是从降低功耗的角度来说,应该关闭。
问:系统时钟可不可以在程序中随时切换?答: 可以,但是由内部再一次切换到外部时应按照技术问答2所介绍的步骤进行切换。
问:使用外部晶振时如何配置芯片的引脚?答:对于芯片上有固定晶振引脚的设备(例如C8051F02X);相应时钟输入引脚按选择的晶振模式自动分配引脚;对于晶振引脚与GPIO共用的芯片(例如C8051F30X);晶振引脚要按下述方式进行设置:(1).外接晶体体时;XTAL1与XTAL2都要配置为模拟输入(2).外接振荡电路为"RC"或"C"方式时,XTAL2引脚要配置为模拟输入(3).外接CMOS时钟电路时,XTAL2引脚要配置为数字输入(4).以上几种方式在引脚的配置中都要使用跳过功能将此引脚跳过问:外接晶振的最高频率是多少?答:外接晶振的最高频率是30MHz模数转换问:从上电(或退出掉电模式)到ADC稳定开始转换需要多长时间?答:模拟建立时间也就是等待参考电平稳定的时间。
C8051F410例程简介
ADC 2个IDAC 1个外部中断Interrupts 1个PCA(可编程计数器阵列)6个PortIO 1个定时器Timer 7个UART 2个Watchdog 1个Oscillators 6个Comparators 1个SMBus 6个SPI 3个ADC例1:单通道输入程序描述:ADC0对P1.1端口输入电压采样2048次,累加后,求平均;结果通过UART输出,到电脑,串口调试程序,接收,显示。
ADC例2:多通道输入程序描述:使用ADC0内部多路选择器,逐个循环采样6个输入端口电压,并输出到电脑显示。
IDAC例:程序描述:使用IDAC输出一个正弦波。
Interrupts例:程序描述:配置外部中断INT0或INT1作为中断源,按键触发中断,执行中断程序(P0.0电平改变,连接在P0.0的LED亮灭)。
PCA例1:8位输出模式PWM波程序描述:利用PCA8位输出模式,输出PWM波。
PCA例2:16位输出模式PWM波程序描述:利用PCA16位输出模式,输出PWM波。
PCA例3:捕获模式程序描述:利用PCA捕获模式,测量输入引脚事件发生时间。
PCA例4:频率输出模式程序描述:利用PCA频率输出模式,产生一个方波,输出到端口。
PCA例5:高速输出模式(?)程序描述:利用PCA高速输出模式,产生一个方波,输出到端口。
PCA例6:软件定时器模式程序描述:利用PCA软件定时器模式,产生定时的中断;中断程序中,触发LED闪耀。
PortIO例1:端口匹配程序描述:配置端口匹配事件作为中断源,程序执行;当按键时,端口匹配事件触发中断,执行中断程序(触发LED亮)。
PortIO例2:数字输入/输出程序描述:演示怎样设置数字输入/输出方式;两个按键和两个LED分别连接到端口;程序持续检测按键,如果按键按下,则点亮下相应的LED。
Timer例1: 8位重载方式程序描述:演示如何使用定时器0的8位定时计数重载方式;利用定时器0在一定频率下产生一个中断,并且,当用户的中断计数到达选择值时,LED被触发。
C8051对硬件SPI接口的设置教程
硬件SPISTC12C5A32S2的硬件SPI接口:MISO P1.6MOSI P1.5SPICLK P1.7/SS P1.4两种操作模式:主模式/从模式功能寄存器名及功能:详见DATASHEET工作模式及时钟频率选择;SPCTL = 0XD0主模式,忽略/SS, SPICLK空闲时为低电平,数据高位先发送,时钟频率=CPU_CLK/4做主机时应注意在SPI中,传输总是由主机启动的。
如果SPO使能(SPEN=1)并选为主机,主机对SPI数据寄存器的写操作将启动SPI的时钟发生器和数据的传输。
在数据写入SPDAT之后的一个到半个SPI位时间后,数据将出现在MOSI脚。
传输完一个字节后,SPI时钟发生器停止,传输完成标志(SPIF)置位并产生一个中断(如果SPI中断使能)。
关于配置中断寄存器:DATASHEET说“要产生SPI中断,需要ESPI/EADC/EA全部为1”,但是实际操作中只需将EA配置为1(总中断打开)就行了,而且ESPI是IE2中的寄存器关于这个问题,我认为是因为这里是MCU做主机,AD5612为从(AD5612只能为从)。
而DATASHEET上的例子为两个MCU,用/SS做主从选择时的应用方法具体程序:/**************************************************函数原型:void readMemoryArrayclock_SPI()功能:SPI发送数据。
***************************************************unsigned char readMemoryArrayclock_SPI(date){SPDAT = date;while(!(SPSTAT & 0x80)); //判断传输是否完成SPSTAT = 0Xc0; //清零(向该两个标志位写“1”,会将它们清零)return date;}/**************************************************函数原型:void writeMemoryArrayclock_SPI()功能:SPI接收数据。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//
// The SPI clock in this example is limited to 500 kHz when used with the
// SPI0_Slave code example. During a SPI_Read, the slave needs some time to
// boards will blink slowly. If it fails, the LEDs will be OFF.
//
//
// Target:
C8051F04x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None // // Release 1.0 // -Initial Revision (TP) // -14 DEC 2006 //
SPI_Data_Array[i] = 0; }
// Read the array back from the slave
SPI_Array_Read ();
while (!NSSMD0);
// Wait until the Read transfer has // finished
// Check if the received array matches the sent array for (i = 0; i < MAX_BUFFER_SIZE; i++) {
EA = 1;
// Enable global interrupts
LED = 0;
SFRPAGE = LEGACY_PAGE;
// TEST BEGIN --------------------------------------------------------------
SPI_Data = test_value;
while (!NSSMD0);
// Wait until the Write transfer has // finished
// Clear SPI_Data_Array for the SPI_Buffer_Read function for (i = 0; i < MAX_BUFFER_SIZE; i++) {
// clocks, a dummy byte between the command and the first byte of Read data
// will be required.
//
// This example is intended to be used with the SPI0_Slave example.
// P0.3 - SPI NSS (digital output, push-pull)
//
// P1.6 - LED
(digital output, push-pull)
//
// all other port pins unused.
//
//
// How To Test:
//
// 1) Download the code to a F040-TB that is connected as above to
#define MAX_BUFFER_SIZE 8
// Maximum buffer Master will send
// Inse SLAVE_LED_ON
0x01
#define SLAVE_LED_OFF 0x02
#define SPI_WRITE
0x04
#define SPI_READ
unsigned char SPI_Data = 0xA5;
unsigned char SPI_Data_Array[MAX_BUFFER_SIZE] = {0};
bit Error_Flag = 0;
unsigned char Command = 0x00;
//----------------------------------------------------------------------------// Function Prototypes //-----------------------------------------------------------------------------
//
// Pinout:
//
// P0.0 - SPI SCK (digital output, push-pull)
// P0.1 - SPI MISO (digital input, open-drain)
// P0.2 - SPI MOSI (digital output, push-pull)
void Watchdog_Init (void); void Oscillator_Init (void); void Port_Init (void); void SPI0_Init (void); void Init_Device (void);
void SPI_LED_On (void); void SPI_LED_Off (void); void SPI_Byte_Write (void); void SPI_Byte_Read (void); void SPI_Array_Write (void); void SPI_Array_Read (void);
void Delay(void);
//----------------------------------------------------------------------------// main() Routine //----------------------------------------------------------------------------void main (void) {
// Write a value SPI_Byte_Write ();
while (!NSSMD0);
// Wait until the Write transfer has // finished
// Read the same value back SPI_Data = 0x00; SPI_Byte_Read ();
unsigned char test_value = 0x55; unsigned char test_array[MAX_BUFFER_SIZE] = {1,2,3,4,5,6,7,8}; unsigned char i;
Init_Device ();
// Initializes hardware peripherals
// interpret the command and write the appropriate data to the SPI0DAT
// register, and the slave no longer has enough time to complete the
// SPI_READ_BUFFER command with a clock greater than 500 kHz. For faster SPI
while (!NSSMD0);
// Wait until the Read transfer has // finished
// Check if the sent value and returned value match if (SPI_Data != test_value) {
Error_Flag = 1; }
#define SYSCLK
24500000 // Internal oscillator frequency in Hz
#define SPI_CLOCK
500000
// Maximum SPI clock // The SPI clock is a maximum of 500 kHz // when this example is used with // the SPI0_Slave code example.
//----------------------------------------------------------------------------// Includes //-----------------------------------------------------------------------------
#include <C8051F040.h>
// SFR declarations
//----------------------------------------------------------------------------// Global Constants //-----------------------------------------------------------------------------
sbit LED = P1^6;
// LED='1' means ON
//----------------------------------------------------------------------------// Global Variables
//-----------------------------------------------------------------------------
0x08
#define SPI_WRITE_BUFFER 0x10
#define SPI_READ_BUFFER 0x20
#define ERROR_OCCURRED 0x40