|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
前端时间晒了自己入手的<MPLAB STARTER KIT FOR PIC18 mcuS>,大概了解了一下之后,发现8位单片机并不适合我玩,因为我习惯了32位单片机的高大上(8位机基本没用过,起步就是16位的MSP430),所以后来又入手了<PIC32 Ethernet Starter Kit II>。
' B, O! P: @) B1 i" ?& [ u
: ^. P% n) u* Y& }( x" ~% I! w! _说说我选择PIC32的理由(这个纯属个业余爱好,就是玩,不用于任何产品),因为平时较多的时候使用Mac Book,Microchip的MPLAB X开发环境是跨平台的,可以运行在windows、linux以及OS X上,能在OS X上很方便玩起来的单片机绝对不多(虽然有GCC这种跨平台神器,但是大家都知道,新手根本玩不转这东西);另外MPLAB X开发环境以及XC系列编译器是免费的,虽然免费的XC编译器好像很渣的样子(不能选择优化)。$ g! C! P7 [/ F
0 a2 P8 q" @9 `& T+ ]PIC32主要包括两大系列,PIC32MX和PIC32MZ,本文主要针对PIC32MX795F512L。PIC32MX7xx采用MIPS32® M4K内核,工作电压2.3V-3.6V,最高主频80MHz。$ D) Y+ g- I1 z
5 ]# _7 Q9 m9 Z6 m! C, p这几天在看一本书《32位单片机C语言编程基于PIC32》,英文名《Programming 32-bit Microcontrollers in C Exploring the PIC32》(下载链接:http://download.eeworld.com.cn/download/lcofjp/62303),在此分享一些心得。+ O* z/ d3 m4 X) m; A. f% h
PIC32也拥有像STM32类似的外设库(PIC32MX Peripheral Library),在使用的时候包含plib.h即可。先来说说IO口,PIC32提供两种调试接口,JTAG和ICSP/ICD接口,要使用PORTA的部分引脚作为IO口,必须禁止JTAG接口:DDPCONbits.JTAGEN = 0; PORTB的大部分引脚与ADC输入引脚复用,复位时被配置为模拟功能,若要作为IO口使用,则需配置ADC模块: AD1PCFG = 0xFFFF; 如果某个外围模块的输入输出引脚与IO端口复用,那么一旦启用该外围设备,它就将完全控制该IO端口,与方向控制寄存器(TRISx)的内容无关,然而在8位架构中,即使该模块需要使用这些引脚,用户也得自己制定每个引脚的正确方向。7 h2 K' ~$ j$ U) c" `
' E1 c+ D" V4 s) j5 {1 u
PIC32的中断分为两种工作模式:单向量工作模式和多向量工作模式。单向量工作模式只有一个中断函数,所有中断都在同一个函数中得到响应(8位单片机基本都是这种模式),可想而知,如果有多个中断要响应,则要判断多个标志位才能确定是产生了哪个中断,因此这种中断响应的延迟很大。多向量工作模式的话,和ARM cortex-M3的原理差不多,可以每个外设模块使用一个中断向量,最多可达64个中断向量。中断优先级分为两种,组优先级和子优先级,组优先级有0-7共8个,上电时,所有中断源的优先级都被默认地设定为ipl0,并屏蔽所有的中断。在相同的组优先级内,还有两个数据位用于定义4个子优先级。如果有2个组优先级相同的事件发生,那么子优先级高者将先被响应。每款PIC32单片机都定义了各种中断源的默认相对优先级。当其他条件都无效时(组优先级和子优先级都相同),将根据自然顺序决定响应同时发生的多个事件中的哪一个。
' e8 T& g8 ?" G' g' a8 G中断函数的写法(其中一种,比较简单的写法):: V& _' Z' [" U$ e% {( W
void __ISR(VECTOR, IPL) HandlerName(void);
1 D( @! o* ^& r7 d其中VECTOR指定要响应的某个中断向量,IPL指定中断的优先级。
8 ?6 l) z& Z4 ?: r1 L1 W8 t例如:7 W Q2 T) K0 D+ F9 z% ]
void __ISR(_TIMER_1_VECTOR, IPL0SOFT) Timer1ISR(void)
- _- Z/ H2 m6 G# R" D+ `$ \% t{, Q$ T1 V- r9 ^9 [3 k) j# }
}
; D. [ ~; l; P最后来个流水灯的示例吧,调了半个晚上才弄出来,问题在于要给FPB进行分频时,就不要执行SYSTEMConfigPeRFormance函数了,它会把FPB调到系统能接受的最大值,导致频率不对。3 `, n5 d9 o( r: n& ^4 ^9 ]" A& x0 ?
+ c' i6 }/ j5 E. a#include <stdio.h>0 D' c7 x) p4 U
#include <stdlib.h> I! { u5 X+ J. d, O
#include <stdint.h>
8 A, P4 e6 c3 w z' a#include <plib.h>
+ y# E1 i. m* e# ?! b$ |4 \3 m- \% ~& y+ a+ k/ W0 N! Z
// DEVCFG3# }) v& P/ x: L8 c2 P7 ^# j$ z) Q
// USERID = No Setting
, H/ }" s. G5 W; G7 _2 _- H#pragma config FSRSSEL = PRIORITY_7 // SRS Select (SRS Priority 7)0 v- F5 _1 c5 _
#pragma config FMIIEN = ON // Ethernet RMII/MII Enable (MII Enabled)' C, F8 \* S$ Q0 P d$ B
#pragma config FETHIO = ON // Ethernet I/O Pin Select (Default Ethernet I/O)9 a3 V. k, _0 l9 ?2 Z
#pragma config FCANIO = ON // CAN I/O Pin Select (Default CAN I/O)
; f7 t) V- m! J3 T6 L. M9 h#pragma config FUSBIDIO = ON // USB USID Selection (Controlled by the USB Module): O7 P# Q$ k' g- a& h' B
#pragma config FVBUSONIO = ON // USB VBUS ON Selection (Controlled by USB Module)
4 i o- L$ `% O" B5 L, E; `/ t+ p/ A9 O0 ]! r
// DEVCFG25 K) ?! R p& s& `0 ], K9 Q5 }' V# n3 a
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (4x Divider)- }: e9 B* N6 ~7 A" \+ M
#pragma config FPLLMUL = MUL_18 // PLL Multiplier (18x Multiplier)3 j% d( E" |% S6 H$ i* J# ?4 d% m# t
#pragma config UPLLIDIV = DIV_1 // USB PLL Input Divider (1x Divider)( F6 a/ X- s! N6 ?
#pragma config UPLLEN = OFF // USB PLL Enable (Disabled and Bypassed)" z% x. Q5 L! O1 J9 `5 a- x
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)' m( e1 `+ Y9 I2 B: N7 ?
% E5 B. F! u$ {// DEVCFG1
+ |8 s0 E( w9 K: Q0 v#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc (XT,HS,EC))
4 V% i2 X* s: g' i: p#pragma config FSOSCEN = ON // Secondary Oscillator Enable (Enabled)( ^( [# F- I [' m, I/ C+ J
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
9 z( T8 S" }$ b+ W#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)6 e. }8 F% Q# |- \4 Z
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)/ F) H$ r. J2 Q' N+ `- L9 G3 X* \, z
#pragma config FPBDIV = DIV_8 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
' @' E' I1 @- i9 e#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
* Z' v4 v% S1 q# K6 U5 n#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
! D- m0 Y% {0 o+ T3 h#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls)): @- k9 h. P5 Y2 I3 a5 i8 v
, h3 N8 C0 t) I, b1 p// DEVCFG0( \; H. v- s2 L' q) B0 x
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)# U6 ~0 P3 L5 I
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)- Z5 k' R& `* f1 N) a$ A7 ]% B
#pragma config PWP = OFF // Program Flash Write Protect (Disable)" C% g' E4 [! E) K% i
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)/ k% \% P: H; ^) o4 t
#pragma config CP = OFF // Code Protect (Protection Disabled)7 t% A- G/ R% C8 B
1 l# L/ ]2 s1 `+ Y; a
/*
* v! s0 U. [' q' K1 r- k2 A* KEY1,2,3 === RD6, RD7, RD13
2 H9 x6 r8 g8 K) Y0 ~9 ]8 ~* LED1,2,3 === RD0, RD1, RD2+ ?- d0 o/ o6 q k \ I9 M
*/# [) W+ ]9 R2 }# ~6 m' P4 U
volatile uint32_t value = 0;1 y* r/ R9 E% N; S2 M2 E
3 \) y* J$ H7 f- P( r6 e5 Aint main(int argc, char** argv) {
, k4 T/ E2 A C/ |, m7 f" c' J F7 A& X) f: h/ c& P4 K+ A
uint32_t old_value = 0;8 ?/ A% f1 D3 J# ~# H% C5 l! t( u
//SYSTEMConfigPerformance(72000000L);
2 C( k+ a5 H3 |8 {- @$ O DDPCONbits.JTAGEN = 0;
9 n6 H, ?4 K, J8 m TRISDCLR = 7;
1 s7 S! z$ N4 ]5 x2 O8 [ PR1 = 35155;
. N4 v) q, G, ^' p5 r5 m T1CON = 0x8030;5 l6 ]! p+ i+ v0 ^; f# N
. {+ r5 o' F& N/ P7 Y& p. G
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);// INTEnableSystemMultiVectoredInt();4 T* x. a! ~& E B. n
mT1SetIntPriority(1);
$ U( T( c: w' {. p7 j0 s mT1IntEnable(1);3 w- u9 ~* ?. U# e. t* w: @
INTEnableInterrupts();
# c! }' }$ N3 r6 ^
& `+ l9 b7 o2 [" a3 _" _% Z while(1)
* o& O; j' d9 j S {$ U/ `7 {+ K) F; @5 X6 Q0 I
if (old_value != value)& ~4 [; T) `! F1 Q. {/ _
{
1 f* }! v/ q, g& ?, { LATD = value;
( `) s% ?) d. v a. d7 z. f+ Q+ } old_value = value;0 S4 _8 _& f8 A! F
} A# e1 U% A1 i$ c* @' Q4 |2 j
}
, `9 |% y ?0 K3 g return (EXIT_SUCCESS);& B+ e5 }1 }1 O4 ]) Z
}
p/ O1 r$ l# H
) _; v7 S' H8 O5 K7 B% |void __ISR(_TIMER_1_VECTOR, IPL1SOFT) Timer1ISR(void)
% h- S7 I" |4 d' p; i{
" p- B P `( w( K8 a; Y switch(value)0 s2 W2 K6 p7 F/ \ |
{
4 @/ t( {5 ]3 g3 u I case 1:
6 [, _4 F4 ]6 M0 r value = 2;
$ h5 {0 s6 B% w9 z" ]0 d! J3 C break;- s# [5 I k. ~! z) k& h( F; l
case 2:
$ [# y9 ?8 j: u' r: L value = 4;
* A- ?+ I8 ^8 N; n" X break;: D" }) c; l! S) j
case 4:- d: b, U9 b5 x) Q& O" k# C, V+ P9 w% V1 L
value = 1;# m( ~ G% S J D5 a3 i; w A
break;. R1 z% o$ K1 q4 Q( K/ W
default:( M! t7 P8 [7 i _
value = 1;5 ]! |% z, Z3 ~/ U* E2 t
break;! U7 M+ Y7 p; y% a- {' A
}
m$ H1 ?! }- M2 d5 ` mT1ClearIntFlag();
; a. r! f9 j% l/ S- F}7 Q. F! h& w' j# h
复制代码 |
|