查看: 2819|回复: 33
|
求助求助:PIC16F876问题
[复制链接]
|
|
各位大大好,小弟是新手,有个问题困扰很久了无法解决..我是用C来写PIC16F876的程序,然后用CCS 的 PCM C Compiler来转换去HEX 格式再烧入IC里.我想用8个pin来output 0-255,既是用RB0到RB7来给binary output.我暂时使用8个LED接在这8个pin上,用来检查output.试了很多方法,可是就是不行。那8个LED完全不亮。除了这8个外,我有用4个PORT A 和3个PORT C,那些的都可以,因为我是用output_high或output_low来控制,至于那8个pin,如果要用output_high/low 来决定output的话,整个program会很大,不能compile.以下是我所写的程序,麻烦各位大大替小弟检查检查和指点。小弟无限感激。程序如下:
#include<16F876.H>
// Define the serial port system and clock oscillation
#use delay(clock=20000000)
#use RS232(baud=115200,xmit=PIN_C6,rcv=PIN_C7)
#fuses hs, nowdt, nolvp, noprotect
// Define the ports that's being been used
#byte PORTC=7
#byte PORTB=8
#byte PORTA=5
// Define parameter used
char a; // ID
char b; // Function Selection
char mode; // Mode Set
char drive; // Driver Mode
char rot; // Rotation Mode
char sys; // System Mode
char chg; // Encoder Changes
char cntplr; // Counter Polarity Set
char rst; // Counter Reset
unsigned int i1; // Motor Rotation Output Angle
unsigned int i2;
unsigned int i3;
// Main program
void main()
{
set_tris_c(0x80);
set_tris_b(0x00);
set_tris_a(0x00);
// Pin testing
output_low(PIN_C0);
output_low(PIN_C1);
output_low(PIN_C2);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
output_low(PIN_A0);
output_low(PIN_A1);
output_low(PIN_A2);
output_low(PIN_A3);
// Only test with rotation angle as it is easy to notice with the LED on microcontroller board
output_high(PIN_B7);
delay_ms(500);
output_high(PIN_B6);
delay_ms(500);
output_high(PIN_B5);
delay_ms(500);
output_high(PIN_B4);
delay_ms(500);
output_high(PIN_B3);
delay_ms(500);
output_high(PIN_B2);
delay_ms(500);
output_high(PIN_B1);
delay_ms(500);
output_high(PIN_B0);
delay_ms(500);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
do
{
a=0;
b=0;
a=getc(); // Get ID
b=getc(); // Get the symbol for which function to run
portb=0; // Set all pins low for no output
while( a == '1' )
{
if( b == 'A'){
mode = getc(); // Get mode set
if( mode == 'C' ){
output_high(PIN_A0);
delay_ms(500);
output_low(PIN_A0);
delay_ms(500);
output_high(PIN_A0);
}
else if( mode == 'T' ){
output_high(PIN_A0);
}
else if( mode == 'F' ){
output_low(PIN_A0);
}
}
else if( b == 'B'){
drive = getc(); // Get driving mode HOM or SERVO
if( drive == 'H'){
output_high(PIN_A1);
}
else if( drive == 'S'){
output_low(PIN_A1);
}
}
else if( b == 'C'){
rot = getc(); // Get rotation mode CW or CCW
if( rot == 'R'){
output_high(PIN_A2);
}
else if( rot == 'C'){
output_low(PIN_A2);
}
}
else if( b == 'D'){
sys = getc(); // Get system set mode
if( sys == 'T'){
output_high(PIN_A3);
}
else if( sys == 'F'){
output_low(PIN_A3);
}
}
else if( b == 'E'){
i1 = getc(); // Get motor positioning rotation angle
i2 = getc();
i3 = getc();
if( i1 == '0' && i2 == '0' && i3 == '0' ){
PORTB=0;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '1'){
PORTB=1;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '2'){
PORTB=2;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '3'){
PORTB=3;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '4'){
PORTB=4;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '5'){
PORTB=5;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '6'){
PORTB=6;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '7'){
PORTB=7;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '8'){
PORTB=8;
break;}
else if( i1 == '0' && i2 == '0' && i3 == '9'){
PORTB=9;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '0'){
PORTB=10;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '1'){
PORTB=11;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '2'){
PORTB=12;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '3'){
PORTB=13;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '4'){
PORTB=14;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '5'){
PORTB=15;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '6'){
PORTB=16;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '7'){
PORTB=17;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '8'){
PORTB=18;
break;}
else if( i1 == '0' && i2 == '1' && i3 == '9'){
PORTB=19;
break;}
else if( i1 == '0' && i2 == '2' && i3 == '0'){
PORTB=20;
break;}
else if( i1 == '2' && i2 == '5' && i3 == '5'){
PORTB=255;
break;}
break;
}
else if( b == 'F'){
chg = getc(); // Get encoder change set
if( chg == 'T'){
output_high(PIN_C0);
}
else if( chg == 'F'){
output_low(PIN_C0);
}
}
else if( b == 'G'){
cntplr = getc(); // Get counter polarity set
if( cntplr == 'T'){
output_high(PIN_C1);
}
else if( cntplr == 'F'){
output_low(PIN_C1);
}
else if( mode == 'C' ){
output_high(PIN_C1);
delay_ms(500);
output_low(PIN_C1);
delay_ms(500);
output_high(PIN_C1);
}
}
else if( b == 'H'){
rst = getc(); // Get counter reset
if( rst == 'T'){
output_high(PIN_C2);
}
else if( rst == 'F'){
output_low(PIN_C2);
}
}
break;
}
while( a != '1') // All output to low if different ID
{output_low(PIN_C0);
output_low(PIN_C1);
output_low(PIN_C2);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
output_low(PIN_A0);
output_low(PIN_A1);
output_low(PIN_A2);
output_low(PIN_A3);
break;}
delay_ms(100);
}while(1);
}
那个部分我只写到20,只用来testing,因为实在懒惰写到255,太长了... 谢谢大家!! |
|
|
|
|
|
|
|
发表于 18-1-2008 03:17 PM
|
显示全部楼层
原帖由 jths21 于 18-1-2008 11:51 AM 发表
各位大大好,小弟是新手,有个问题困扰很久了无法解决..我是用C来写PIC16F876的程序,然后用CCS 的 PCM C Compiler来转换去HEX 格式再烧入IC里.我想用8个pin来output 0-255,既是用RB0到RB7来给binary output.我暂时使用8个LED接在这8个pin上,用来检查output.试了很多方法,可是就是不行。那8个LED完全不亮。除了这8个外,我有用4个PORT A 和3个PORT C,那些的都可以,因为我是用output_high或output_low来控制,至于那8个pin,如果要用output_high/low 来决定output的话,整个program会很大,不能compile.以下是我所写的程序,麻烦各位大大替小弟检查检查和指点。小弟无限感激。程序如下:
如果你是用其他的C, 我就帮不了你。
其实, 用CCS C很容易实现你要的东西。
下面的code已测试, ok的。
你用什么版本, 请注明。
- // By Pic@cARi
- // 18 Jan 2008
- // Accept input from RS232, and put in PortB.
- #include <16F877A.H>
- #use delay(clock=20000000)
- #use RS232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
- #fuses hs, nowdt, nolvp, noprotect
- #byte PORTB=0x06
- #Use fast_IO(b)
- #include <STDLIB.h>
- #include <input.c>
- int value;
- void main()
- {
- portb=0;
- set_tris_b(0b00000000);
- while(true)
- {
- value = get_int();
- PortB=value;
- }
- }
复制代码 |
|
|
|
|
|
|
|
楼主 |
发表于 18-1-2008 03:22 PM
|
显示全部楼层
现在我有MPLAB IDE 8.0和 HITEC PICC v8.05PL2...
我再尽力试试看,非常谢谢你的资料.. |
|
|
|
|
|
|
|
发表于 18-1-2008 06:25 PM
|
显示全部楼层
|
|
|
|
|
|
|
楼主 |
发表于 19-1-2008 08:37 AM
|
显示全部楼层
那么CCSC v2.734 的 PCM C Compiler 可以用吗? |
|
|
|
|
|
|
|
发表于 19-1-2008 08:50 AM
|
显示全部楼层
原帖由 jths21 于 19-1-2008 08:37 AM 发表
那么CCSC v2.734 的 PCM C Compiler 可以用吗?
可以。 那个是DOS based的, 是哪里拿到的?
你可以下载CCS C的 4.x Demo 版, 必要时Driver我给你。 |
|
|
|
|
|
|
|
楼主 |
发表于 19-1-2008 08:55 AM
|
显示全部楼层
那个是我从朋友那里拿的...我刚试过了,那个有个header file 里面的 input.c 里的 digit = getch(); 过不了...那里写 Error file not found.<34>...那个demo版不支援PIC16F876...
然后我试着不放 input.c下去,只放 stdio.h,ctype.h,和 16f876.h,可以compile,不过我现在不在学校,不能测试...我是用那个dos 版的来弄...
[ 本帖最后由 jths21 于 19-1-2008 01:27 PM 编辑 ] |
|
|
|
|
|
|
|
发表于 19-1-2008 03:44 PM
|
显示全部楼层
原帖由 jths21 于 19-1-2008 08:55 AM 发表
那个是我从朋友那里拿的...我刚试过了,那个有个header file 里面的 input.c 里的 digit = getch(); 过不了...那里写 Error file not found....那个demo版不支援PIC16F876...
然后我试着不放 input.c下去,只放 std ...
input.c 是CCS C的Driver, 在PICC/Drivers 里。
Demo 可以Compile 16F877A, 可以在16F876A里跑。
下面的code, 我已经把Input.c 的code include进来了。
你可能看不懂, 但不要去改它,
重点你会用 get_int() 这个function就好了。
get_int() 会return 你从RS232里打进去的。
x=get_int() ;
如你输入 '3' ,'5' <Enter>
那 x 会得到35 (integer)。- // By Pic@cARi
- // 19 Jan 2008
- // Accept input from RS232, and put in PortB.
- #include <16F877A.H> // can be use for 16F876A
- #use delay(clock=20000000)
- #use RS232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
- #fuses hs, nowdt, nolvp, noprotect
- #byte PORTB=0x06
- #Use fast_IO(b)
- //=========================
- // Modified from CCS C Driver
- // partial content of Input.c
- signed int atoi(char *s)
- {
- signed int result;
- unsigned int index;
- char c;
- index = 0;
- result = 0;
- if (!s) return 0;
- // Omit all preceeding alpha characters
- c = s[index++];
- if (c >= '0' && c <= '9')
- {
- // The number is a decimal number
- while (c >= '0' && c <= '9')
- {
- result = 10*result + (c - '0');
- c = s[index++];
- }
- }
- return(result);
- }
- void get_string(char* s, unsigned int8 max)
- {
- unsigned int8 len;
- char c;
- --max;
- len=0;
- do {
- c=getc();
- if(c==8) { // Backspace
- if(len>0) {
- len--;
- putc(c);
- putc(' ');
- putc(c);
- }
- } else if ((c>=' ')&&(c<='~'))
- if(len<=max)
- }
- s[len++]=c;
- putc(c);
- }
- } while(c!=13);
- s[len]=0;
- }
- signed int8 get_int()
- {
- char s[5];
- signed int8 i;
- get_string(s, 5);
- i=atoi(s);
- return(i);
- }
- // End of Driver
- //==========================================
- int value;
- // Your Main Code goes here
- void main()
- {
- portb=0;
- set_tris_b(0b00000000);
- while(true)
- {
- value = get_int();
- PortB=value;
- }
- }
复制代码 |
|
|
|
|
|
|
|
楼主 |
发表于 19-1-2008 04:18 PM
|
显示全部楼层
就是说我直接把你写的driver code 放进我的main program就好了?
是放在要用的那part上面还是整个program之前呢?
我尽力试试...非常感谢你的帮忙... |
|
|
|
|
|
|
|
楼主 |
发表于 19-1-2008 11:16 PM
|
显示全部楼层
刚才用demo版本试了,可以过,但是现在没得测试,所以不懂还可以不可以。但是我用的是876罢了,不是876A,是可以的吗?
我是用877A来compile它...我放上来给你看看...希望可以过,这问题困扰有2个星期多了...唉... |
|
|
|
|
|
|
|
发表于 20-1-2008 02:28 AM
|
显示全部楼层
其实楼主要的是从serial port拿到data,然后再perform task base on data是吗? |
|
|
|
|
|
|
|
楼主 |
发表于 20-1-2008 08:10 AM
|
显示全部楼层
原帖由 fritlizt 于 20-1-2008 02:28 AM 发表
其实楼主要的是从serial port拿到data,然后再perform task base on data是吗?
对...可是就只有一个part弄不好...其他part都可以,就不知为什么要用8pins来output 255 binary data这么麻烦....
基本上我所知道的是可以用 portb=i; (i是0-255数字),可是不懂为什么就是不能...
[ 本帖最后由 jths21 于 20-1-2008 08:11 AM 编辑 ] |
|
|
|
|
|
|
|
楼主 |
发表于 21-1-2008 10:08 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 21-1-2008 11:13 AM
|
显示全部楼层
原帖由 jths21 于 20-1-2008 08:10 AM 发表
对...可是就只有一个part弄不好...其他part都可以,就不知为什么要用8pins来output 255 binary data这么麻烦....
基本上我所知道的是可以用 portb=i; (i是0-255数字),可是不懂为什么就是不能...
其实, 你PC那个部分是用人手打进去的( 通过HyperTerminal), 还是写程序如VB呢?
上面我给你的程序是用Hyperteminal 输入, 然后处理, 看起来会复杂。。。
你可以直接send ASCII 0-255 (1byte),
- =========================
- CCS C
- int x;
- x=getc();
- portb=x;
-
- =========================
- VB
- x=1
- MSCOMM1.output= chr(x)
- =========================
复制代码
compilier 过期, 把日期roll back就可以了。 |
|
|
|
|
|
|
|
楼主 |
发表于 21-1-2008 11:36 AM
|
显示全部楼层
暂时我是人手key in...迟些我会做个VB program来操作... |
|
|
|
|
|
|
|
发表于 21-1-2008 12:01 PM
|
显示全部楼层
原帖由 jths21 于 21-1-2008 11:36 AM 发表
暂时我是人手key in...迟些我会做个VB program来操作...
你好像还抓不到我上一楼的重点。。。 |
|
|
|
|
|
|
|
楼主 |
发表于 21-1-2008 12:24 PM
|
显示全部楼层
原帖由 pic 于 21-1-2008 12:01 PM 发表
你好像还抓不到我上一楼的重点。。。
你想说的是用vb会方便很多对吗?
可是我还没进入vb的那个方向...所以目前testing都是用手打的... |
|
|
|
|
|
|
|
发表于 21-1-2008 01:00 PM
|
显示全部楼层
原帖由 jths21 于 21-1-2008 12:24 PM 发表
你想说的是用vb会方便很多对吗?
可是我还没进入vb的那个方向...所以目前testing都是用手打的...
不是啦, 你要0~255, 你可以直接send那个Byte, 那MCU的部分就很简单很简单了。。。。
或你用SIOW.exe , 和CCS C一起来的, 你可以send Hex。
或看什么Hyperterminal 可以输入 hex data的。。。
因为不知道你的应用, 也不懂适合你吗。。。 |
|
|
|
|
|
|
|
楼主 |
发表于 21-1-2008 01:09 PM
|
显示全部楼层
原帖由 pic 于 21-1-2008 01:00 PM 发表
不是啦, 你要0~255, 你可以直接send那个Byte, 那MCU的部分就很简单很简单了。。。。
或你用SIOW.exe , 和CCS C一起来的, 你可以send Hex。
或看什么Hyperterminal 可以输入 hex data的。。。
因为不知 ...
其实我懂真正只需要2,3行罢了,但是现在就不明白testing为何跑不了...可能需要真正vb program出来....
我试过了你给我的那个input.c的间接法,还是不行
[ 本帖最后由 jths21 于 21-1-2008 01:12 PM 编辑 ] |
|
|
|
|
|
|
|
发表于 21-1-2008 01:28 PM
|
显示全部楼层
原帖由 jths21 于 21-1-2008 01:09 PM 发表
其实我懂真正只需要2,3行罢了,但是现在就不明白testing为何跑不了...可能需要真正vb program出来....
我试过了你给我的那个input.c的间接法,还是不行
baud rate 是9600, 不是115200.
你的RS232的部分对吗?
你可以test:
putc( getc()+1);
你打A, 它要return B。
你打1, 它要return 2。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|