佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 2350|回复: 23

UART

[复制链接]
发表于 17-11-2006 05:47 AM | 显示全部楼层 |阅读模式
什么是 UART?
大概是怎样用的?
UART 16550 需要写 assembly language 去 program 它吗?

[ 本帖最后由 kevy 于 21-11-2006 10:18 PM 编辑 ]
回复

使用道具 举报


ADVERTISEMENT

发表于 17-11-2006 05:09 PM | 显示全部楼层
原帖由 kevy 于 17-11-2006 05:47 AM 发表
什么是 UART?
大概是怎样用的?
UART 16550 需要写 assembly language 去 program 它吗?

UART 16550, 就是PC 的Serial Port /RS232。
如有疑问请再问。
回复

使用道具 举报

 楼主| 发表于 17-11-2006 10:20 PM | 显示全部楼层

回复 #2 pic 的帖子

你的意识 UART 16550 是电脑 Serial Port 的插头吗?
为什么还有人说它是一个 IC 给与电脑和 microcontroller 地联接系统?
是我搞错了吗?
回复

使用道具 举报

发表于 18-11-2006 10:45 AM | 显示全部楼层
你的意思 UART 16550 是电脑 Serial Port 的插头吗?

UART 16550 , 是IC, 多用在PC 电脑里。
在电脑里它“独立”负责Serial communication, 它也有buffer, 电脑在忙时,它还会继续接收Serial data, 电脑在得空了, 就会像它要data。

一般上, 我们不会去买这颗IC来用在Microcontroller 里, 因为一些MCU有内建USART了。

UART 16550 需要写 assembly language 去 program 它吗?

如果你是用DOS, 你可以写ASM / C 去Program 它, program 它的Baud rate, interrupt, Read receive buffer, send character 等等。

但今天, 我都不会这样做, 如我要access 我电脑里的UART, 简单的我会用VB的MsComm ActiveX 来完成。

为什么还有人说它是一个 IC 给与电脑和 microcontroller 地联接系统?

没说错啊。。。
回复

使用道具 举报

 楼主| 发表于 18-11-2006 11:49 AM | 显示全部楼层

回复 #4 pic 的帖子

谢谢 pic 大哥的教导,我现在知道 UART 的用除了。

但是很不幸的, 我用了一个 PIC16F84A 的 MPU 是没有 USART 的功能。
我现在不知道要该如何传送 DATA 去电脑。我电脑用了 9600kps baud rate, 而我又不会怎样去 deal with 他们的 transmission speed....

pic 大哥!! 可以给我指点吗?

我是否要接一个 UART16550 的 IC 在 PIC16F84A 和 MAX232 之间, 然后才接去电脑的 serial com port 呢?

我的 idea 是想把 program 好的 PIC16F84A (没有写 delay tramission time 的方程式) 传送 serial data 去 UART16550。
UART 16550 将 buffer 了的 seial data 再 send 去电脑经过 MAX 232 的 IC。
当我在 VB 的 MsComm ActiveX 里 set 好了 com port 1, baudrate =9600kps
我的电脑就会读取 PIC16F84A 的 data 了。
不知行不行得通呢... pic 大哥?
回复

使用道具 举报

发表于 18-11-2006 03:36 PM | 显示全部楼层
很简单的事, 你把它搞复杂了。

PIC16F84A 是没有Build-in USART, 但我们可以做Software UART, 一样可以, 没问题的。
Hardware的接法, 请参考我之前发的“MAX232 替代电路”,电路1。


你用什么language ?什么Compiler 来编程?
还有, 你最终要达到的是什么?或最终的应用是什么?

搞清楚了,才可以建议你接下来怎样做。

[ 本帖最后由 pic 于 18-11-2006 03:41 PM 编辑 ]
回复

使用道具 举报

Follow Us
 楼主| 发表于 18-11-2006 07:13 PM | 显示全部楼层

回复 #6 pic 的帖子

谢谢 pic 大哥告诉我去参考 MAX232 替代电路。我已经看过了。 但是我用了 MAX232 连接去 Hardware。

我用 MPLAB IDE v7.42 来 compile assembly language。 我是想用 VB programming language 来联系电脑和 hardware。

我最终要达到的目的是把 analogue value 换成的 digital value, 然后 store 进去 8 个 pic16f84a 的 input pin (port B)。 接着, 其中的一个 pic16f84a pin (from port A) 出 serial output。
而电脑 可以读取 serial output 的资料 (digital value = 0.0V 到 5.0V)。

现在,我面对的问题是不知该怎样处理它们的 transmission speed/ buffer 的问题,所以才想用 UART。

pic 大哥,怎样做 Software UART 呢?
可以建议我接下来该怎样做吗?
回复

使用道具 举报

发表于 19-11-2006 11:11 AM | 显示全部楼层
还好你把最终要达到的目说出来,因为不可行,16F84a 没有ADC, 所以你不能轻易的把 analogue voltage 换成的 digital value。在做project之前, 要先查看Datasheet。
当然, 可能有人告诉你可以加ADC converter  之类IC,但我不建议初学者。

怎样做 Software UART 呢?

Software UART, 你可以去PICLIST 网站 (www.piclist.com)慢慢去挖。

可以建议我接下来该怎样做吗?

如你是初学者,你要成功率高的,最简单的做法,就是用16F877A。
我假设你有烧录器可以烧录16F877A.
16F877A 有8 个ADC input, 有Hardware USART, 满足你project的基本硬件要求。

Compiler 编译器, 如可以,不要用ASM + MPLAB, 改用CCS C compiler, 用C language简单多了, 可以很轻易的做到你要的东西。

你决定吧。。。
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 19-11-2006 06:52 PM | 显示全部楼层

回复 #8 pic 的帖子

pic 大哥!! 太迟了。 我已经买了 ADC0804 来换 analogue to digital 了。
而且,我看过了 16F877 的 datasheet。
我不能成功的 program ADC 和 USART, 所以我采用了 16F84A。
我已经写了一个 program, 但是不知 transmission time 的程式是否有错误。
还有一个大难题, 我也不知该怎么写电脑 program 去读取 16F84A 的 资料。。。

pic 大哥!! 难道没有其他的方法吗?

PROCESSOR 16f84a
#include "p16f84a.inc"
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

#DEFINE TRANSMIT PORTA,1
STATUS equ 03h
TRISA equ 85h
TRISB equ 86h
PORTA equ 05h
PORTB equ 06h
ADCIN equ 0ch
RS232TEMP equ 0dh

ORG 00h
GOTO MAIN

BITDELAY
MOVLW 1eh
MOVWF RS232TEMP

WAITLOOP
DECFSZ RS232TEMP,F
GOTO WAITLOOP
RETURN

SEND1
BSF TRANSMIT
CALL BITDELAY
RETURN

SEND0
BCF TRANSMIT
CALL BITDELAY
RETURN

MAIN
BSF STATUS,5
MOVLW b'00000100'
MOVWF TRISA
MOVLW b'11111111'
MOVWF TRISB
BCF STATUS,5
CLRF PORTA
CLRF PORTB
BSF TRANSMIT

READADC
MOVF PORTB,W
MOVWF ADCIN

BTFSS PORTA,2
GOTO NODATASEND
GOTO DATASEND

NODATASEND
CLRF PORTB
GOTO READADC

DATASEND
BCF TRANSMIT
CLRF PORTA
CALL BITDELAY

LOOP:
LOCAL i=0
WHILE i<8
BTFSC ADCIN,i
CALL SEND1
BTFSS ADCIN,i
CALL SEND0
i=i+1
ENDW

BSF TRANSMIT
CALL BITDELAY
CALL BITDELAY
GOTO READADC
END
回复

使用道具 举报

发表于 20-11-2006 10:30 AM | 显示全部楼层
我已经写了一个 program, 但是不知 transmission time 的程式是否有错误。

老实说,你的code错到完。。。相信你自己也不懂在写什么。。。
RS232 最重要的是Timing, 你没有timing控制(有快有慢), 你只送8bit,但RS232 的1byte 是10bit,是由 1 Start bit+ 8bit data+ 1Stop bit组成,这个你事先知道吗?
初学者要写自己的Software USART,要付出很大的代价,你要读很多资料,并100% 了解才会成功。

我很少,也不很会写ASM,我都直接用C compiler 来完成。
就好像你要做数学的加减乘除,你不会想用笔算,你会去找“计算机”代劳,比较快嘛。。。
而CCS C compiler, 就是我的代劳“计算机”, 花钱买它就是要它为我工作。

1。下面的C code,用16F877, 读ADC AN0, 送去RS232, 9600baud rate。
给你参考, 不到15行, 就这么简单。

  1. // The very basic code to read ADC value and put in RS232 (1 byte)
  2. #include <16F877.h>
  3. #device ADC=8 //configure 8bit for ADC
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP
  5. #use delay(clock=20000000) // Use 20Mhz clock
  6. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

  7. void main()
  8. {
  9.    int value;
  10.    setup_port_a( ALL_ANALOG ); // Configure PortA as Analog port
  11.    setup_adc( ADC_CLOCK_INTERNAL );
  12.    set_adc_channel( 0 ); // Set channel 0

  13.    while(1)
  14.    {
  15.       value = Read_ADC(); // Get ADC
  16.       printf("%u",value);  // send to PC in ASCII mode(0-255)
  17.       delay_ms(1000); // Delay 1sec
  18.    }   
  19. }

复制代码


2。下面的C code,用16F84A, 读ADC0804, 送去RS232,
给你参考:

  1. // The very basic code to read ADC value and put in RS232 (1 byte)
  2. // 16F84A , use Software UART, read ADC0804 at PortB
  3. #include <16F84A.h>
  4. #device ADC=8 //configure 8bit for ADC
  5. #fuses HS,NOWDT,NOPROTECT
  6. #use delay(clock=20000000) // Use 20Mhz clock
  7. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1)

  8. void main()
  9. {
  10.    int value;
  11.    while(1)
  12.    {
  13.       value = value = input_b(); // Get PortB, data from ADC0804
  14.       printf("%u",value);  // send to PC in ASCII mode(0-255)
  15.       delay_ms(1000); // Delay 1sec
  16.    }   
  17. }

复制代码

还有一个大难题, 我也不知该怎么写电脑 program 去读取 16F84A 的 资料。。。

先不管这个, 你要看MCU送出的Data, 可以用HyperTerminal 之类的software 去读RS232收到的资料。
你成功了以后再教你用VB写程序。
回复

使用道具 举报

发表于 21-11-2006 02:05 AM | 显示全部楼层
原帖由 pic 于 20-11-2006 10:30 AM 发表

老实说,你的code错到完。。。相信你自己也不懂在写什么。。。
RS232 最重要的是Timing, 你没有timing控制(有快有慢), 你只送8bit,但RS232 的1byte 是10bit,是由 1 Start bit+ 8bit data+ 1Stop bit组成 ...

你用的是有build in library的吧?
他没有的话要怎样做?
回复

使用道具 举报

发表于 21-11-2006 10:38 AM | 显示全部楼层
原帖由 fritlizt 于 21-11-2006 02:05 AM 发表

你用的是有build in library的吧?
他没有的话要怎样做?

你放心,他问时我会告诉他接下来怎么做, 不会点他去死路,或给没有建设性的,不能达到的回覆,这就是为什么我每次都要问网友是什么应用,了解了才做回覆。
问题是,现在都不知道楼主要用ASM 还是C?

没有C Compiler可以下载 Free Demo, 足够应付楼主的应用。
http://www.ccsinfo.com/content.php?page=compdemo

要RS232 的ASM routine sample,可以到PICLIST找。
http://www.piclist.com/techref/microchip/rs232.htm
看Using internal hardware
看Software only (bit bang)

[ 本帖最后由 pic 于 21-11-2006 10:48 AM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 22-11-2006 10:25 AM | 显示全部楼层

回复#10 pic 的帖子

pic 大哥, 我用了你推荐的 CCS C Compiler (DEMO)。

我成功 compile 了你给我的 pic16F877 的 C code。但是不能成功地把 pic16F84A c code compile.
我看过了它的 device folder 里只有 16F877A, 16C554, 16F877 和 18F458 的 header file, 而我用着的 pic16f84a 没有在这里。
所以,我找了 16F84A 的 header file 放进了它的 device folder。

  1. //////// Standard Header file for the PIC16F84A device ////////
  2. #device PIC16F84A
  3. #nolist
  4. /////////////////////////////// I/O definitions for INPUT() and OUTPUT_xxx()
  5. #define PIN_A0  40
  6. #define PIN_A1  41
  7. #define PIN_A2  42
  8. #define PIN_A3  43
  9. #define PIN_A4  44

  10. #define PIN_B0  48
  11. #define PIN_B1  49
  12. #define PIN_B2  50
  13. #define PIN_B3  51
  14. #define PIN_B4  52
  15. #define PIN_B5  53
  16. #define PIN_B6  54
  17. #define PIN_B7  55

  18. /////////////////////////////// Useful defines
  19. #define FALSE 0
  20. #define TRUE 1

  21. #define BYTE int
  22. #define BOOLEAN short int

  23. #define getc getch
  24. #define getchar getch
  25. #define puts(s) {printf(s); putchar(13); putchar(10);}
  26. #define putc putchar

  27. /////////////////////////////// Constants used for RESTART_CAUSE()
  28. #define WDT_FROM_SLEEP  0
  29. #define WDT_TIMEOUT     8
  30. #define MCLR_FROM_SLEEP 16
  31. #define NORMAL_POWER_UP 24
  32. /////////////////////////////// Constants used for SETUP_COUNTERS()
  33. #define RTCC_INTERNAL   0
  34. #define RTCC_EXT_L_TO_H 32
  35. #define RTCC_EXT_H_TO_L 48
  36. #define RTCC_DIV_2      0
  37. #define RTCC_DIV_4      1
  38. #define RTCC_DIV_8      2
  39. #define RTCC_DIV_16     3
  40. #define RTCC_DIV_32     4
  41. #define RTCC_DIV_64     5
  42. #define RTCC_DIV_128    6
  43. #define RTCC_DIV_256    7
  44. #define WDT_18MS        8
  45. #define WDT_36MS        9
  46. #define WDT_72MS       10
  47. #define WDT_144MS      11
  48. #define WDT_288MS      12
  49. #define WDT_576MS      13
  50. #define WDT_1152MS     14
  51. #define WDT_2304MS     15
  52. #define L_TO_H              0x40
  53. #define H_TO_L                 0

  54. #define RTCC_ZERO           0x0B20    // Used for ENABLE/DISABLE INTERRUPTS
  55. #define INT_RTCC            0x0B20    // Used for ENABLE/DISABLE INTERRUPTS
  56. #define RB_CHANGE           0x0B08    // Used for ENABLE/DISABLE INTERRUPTS
  57. #define INT_RB              0x0B08    // Used for ENABLE/DISABLE INTERRUPTS
  58. #define EXT_INT             0x0B10    // Used for ENABLE/DISABLE INTERRUPTS
  59. #define INT_EXT             0x0B10    // Used for ENABLE/DISABLE INTERRUPTS

  60. #define GLOBAL              0x0B80    // Used for ENABLE/DISABLE INTERRUPTS
  61. #undef GLOBAL
  62. #define GLOBAL              0x0B80    // Used for ENABLE/DISABLE INTERRUPTS
  63. #define INT_EEPROM          0x0B40    // Used for ENABLE/DISABLE INTERRUPTS

  64. #list
复制代码


还是失败的 compile 呢.....
当我 compile 的时候,它显示的 error message 是 "unknown device type "
该怎么处理呢?

// The very basic code to read ADC value and put in RS232 (1 byte)
#include <16F877.h>
#device ADC=8 //configure 8bit for ADC
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000) // Use 20Mhz clock
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

void main()
{
   int value;
   setup_port_a( ALL_ANALOG ); // Configure PortA as Analog port
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel( 0 ); // Set channel 0

   while(1)
   {
      value = Read_ADC(); // Get ADC
      printf("%u",value);  // send to PC in ASCII mode(0-255)
      delay_ms(1000); // Delay 1sec
   }   
}

这个 program 是不断传送 DATA 去 PC 的吗?
如果要制定 user 在 PC 里 request data (send command signal) to uC 是否要加
if input =1
      while(1) {.....}
else ....

很抱歉,对于 C language... 我不太会。 但是我很想去了解。
关于 #device ADC=8 //configure 8bit for ADC 是指从 ADC 来的 source 有 8 个 bits?

关于#use delay(clock=20000000) // Use 20Mhz clock
我看过 16F877 datasheet 的 clocking 是到 16Mhz 配合 11uF-33uF 的 capacitor.
而 16F84A datasheet 的 clocking 是到 10Mhz 配合 11uF-33uF 的 capacitor.
采用 20Mhz 的 crystal 真的可以吗? 要配合多少到多少的 capacitor 呢?
我听别人说 "20Mhz 太快了。可能 uC support 不到那么快的 speed."

关于 setup_port_a( ALL_ANALOG ); // Configure PortA as Analog port
port A 是 8 个从 ADC 来得 inputs?
如果是,为什么还要放 ( ALL_ANALOG )呢? ADC 已经把 analog convert 去 digital 了,不是吗?
setup_adc( ADC_CLOCK_INTERNAL ) 是代表什么?

关于printf("%u",value);  // send to PC in ASCII mode(0-255)
是不是只能传送 ASCII 去 PC 呢? 可不可以传送 decimal value 或 1 bytes 的 binary code 去 PC 呢?

我对 C compiler 渐渐的有兴趣了。 但是还需要点时间去消化。
pic 大哥,我要向你多多学习呢!!

*采用 pic16f84a 有办法吗?
回复

使用道具 举报

发表于 22-11-2006 03:51 PM | 显示全部楼层
pic 大哥, 我用了你推荐的 CCS C Compiler (DEMO)。
我成功 compile 了你给我的 pic16F877 的 C code。但是不能成功地把 pic16F84A c code compile.
我看过了它的 device folder 里只有 16F877A, 16C554, 16F877 和 18F458 的 header file, 而我用着的 pic16f84a 没有在这里。所以,我找了 16F84A 的 header file 放进了它的 device folder。
还是失败的 compile 呢.....
当我 compile 的时候,它显示的 error message 是 "unknown device type "
该怎么处理呢?

CCS C Demo 不支持16F84A。不要紧,我送你旧的CCS Dos版本。

这个 program 是不断传送 DATA 去 PC 的吗?

每一秒送一次。

如果要制定 user 在 PC 里 request data (send command signal) to uC 是否要加
if input =1
      while(1) {.....}
else ....

改成以下,PC , hyperterminal, 按 'Q' 键 , 就会收到PIC送来的ADC data。

  1.    while(1)
  2.    {
  3.       if(getc()=='Q' ) // Wait for character "Q" arrive
  4.       {  
  5.           value = Read_ADC(); // Get ADC
  6.          printf("%u",value);  // send to PC in ASCII mode(0-255)
  7.        }      
  8.     // delay_ms(1000); // Delay 1sec
  9.    }  
复制代码


getc( ), 就是读PC来的character (1 byte)。


很抱歉,对于 C language... 我不太会。 但是我很想去了解。
关于 #device ADC=8 //configure 8bit for ADC 是指从 ADC 来的 source 有 8 个 bits?

16F877A 的ADC其实是10bit (0~1023),这里我们限制去8bit(0~255)

关于#use delay(clock=20000000) // Use 20Mhz clock
我看过 16F877 datasheet 的 clocking 是到 16Mhz 配合 11uF-33uF 的 capacitor.
而 16F84A datasheet 的 clocking 是到 10Mhz 配合 11uF-33uF 的 capacitor.
采用 20Mhz 的 crystal 真的可以吗? 要配合多少到多少的 capacitor 呢?

16F84A version可以去到20Mhz, 16F84 (non A version)就不可以。
既然可以,我们都是用最快的20Mhz Xtal, 配合 22pF的cap。 (不是uF)
你做Software UART,更加要快~~~!

以后不要在买/用16F84A(1K rom) 了, 替代的是16F628A。 (2K rom)

我听别人说 "20Mhz 太快了。可能 uC support 不到那么快的 speed."

20Mhz我还嫌慢呢, PIC18FXXXX 可以去到40Mhz 呢。。。

关于 setup_port_a( ALL_ANALOG ); // Configure PortA as Analog port
port A 是 8 个从 ADC 来得 inputs?
如果是,为什么还要放 ( ALL_ANALOG )呢? ADC 已经把 analog convert 去 digital 了,不是吗?
setup_adc( ADC_CLOCK_INTERNAL ) 是代表什么?

如你看16F877A的datasheet, PortA 可以是Digital 或Analog, 或Mix (Digital +Analog)的组合。
setup_port_a( ALL_ANALOG ) 意思是把整个PortA 都设定成Analog。
然后用set_adc_channel( x ); 来决定是读那一个pin。

setup_adc( ADC_CLOCK_INTERNAL ) , 是使用MCU的内建Clock。

  1. setup_adc (mode);
  2. Parameters:
  3. mode- Analog to digital mode.  The valid options vary depending on the device.  See the devices .h file for all options.  Some typical options include:
  4. ·   ADC_OFF(关,没耗电)
  5. ·   ADC_CLOCK_INTERNAL (较慢,但省电)
  6. ·   ADC_CLOCK_DIV_32 (快,但耗电)
复制代码


关于printf("%u",value);  // send to PC in ASCII mode(0-255)
是不是只能传送 ASCII 去 PC 呢? 可不可以传送 decimal value 或 1 bytes 的 binary code 去 PC 呢?

可以啊,游戏规则是你定的。。。。

  1.    while(1)
  2.    {
  3.       if(getc()=='Q') // Wait for character "Q" arrive
  4.       {  
  5.           value = Read_ADC(); // Get ADC
  6.           putc(value);  // send 1 byte to PC in binary mode(0-255)
  7.        }      
  8.    }  
复制代码

我对 C compiler 渐渐的有兴趣了。 但是还需要点时间去消化。
pic 大哥,我要向你多多学习呢!!

希望不是3分钟热度。。。
要深入,不是为了交功课而学的话,欢迎你来我的PIC Training,  (当然是要收费的, 不然我吃什么?)



*采用 pic16f84a 有办法吗?

用旧的CCS Dos版本。

  1. // The very basic code to read ADC value and put in RS232 (1 byte)
  2. // 16F84A , use Software UART, read ADC0804 at PortB
  3. #include <16F84A.h>
  4. #fuses HS,NOWDT,NOPROTECT
  5. #use delay(clock=20000000) // Use 20Mhz clock
  6. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) // Setup RS232, (Software USART)
  7. #byte PortB =0x06

  8. void main()
  9. {
  10.    int value;
  11.    set_tris_b(0b00000000);// Setup portB as digital output

  12.    while(1)
  13.    {
  14.       if(getc()=='Q')
  15.       {
  16.        value = PortB; // Get PortB, data from ADC0804
  17.        printf("%u",value);  // send to PC in ASCII mode(0-255)
  18.       }
  19.    }   
  20. }

复制代码


既然要学,为什么不买一颗16F877A?什么原因?
回复

使用道具 举报

 楼主| 发表于 24-11-2006 09:19 AM | 显示全部楼层

回复 #14 pic 的帖子

谢谢 pic 大哥送我 CCS DOS 的版本。
关于 PIC TRAINING, 我很有兴趣。 只不过... 地点和学费是那里和多少呢?
谢谢 pic 大哥告诉我关于 PIC TRAINING。我会 follow up training details 的。


  1. 既然要学,为什么不买一颗16F877A?什么原因?
复制代码


我原先没好好地想清楚, 只顾这需要用 10个 I/O pins。
所以采用了 PIC16F84A, 后来才发现 interface 的麻烦呢...
我刚刚才买了 877A, 打算下一次才用。


  1. #fuses HS,NOWDT,NOPROTECT
复制代码



我是用 20MHz 的crystal 应该放 XT 还是放回 HS?
NOWDT = OFF WATHCHDOG TIMER, NOPROTECT = OFF PROTECTION
那么, POWER WRITE 该放 ENABLE 或 DISABLE 吗?


  1. #byte PortB =0x06
复制代码

是指 PORT B 的 ADDRESS 是在 06H?


  1. set_tris_b(0b00000000);// Setup portB as digital output
复制代码

是指 PORT B 是 uC 的 output?
如果要放 uC 的 PORT B 是 input (从 ADC 来的 output), 是不是应该放
set_tris_b(0b11111111);
而 (0bXXXXXXXX)的 b 之前有个 0 代表什么呢?

// The code to read ADC value and put in RS232 (1 byte)
// 16F84A , use Software UART, read ADC0804 at PortB
#include <16F84A.h>
#fuses XT,NOWDT,NOPROTECT  //Crystal = XT
#use delay(clock=20000000) // Use 20Mhz clock
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) // Setup RS232 (Software USART)
                                               //pin A0 transmit data serially to PC
                                               //pin A1 receive command signal from PC
#byte PortB =0x06   //define address PORT B at 06h

void main()
{
   int value;
   set_tris_b(0b11111111);   // Setup portB as digital input from ADC to uC

   while(1)
   {
      if(getc()=='Q')   // Wait for character "Q" arrive
      {
       value = PortB;   // Get PortB, data from ADC0804
       putc (value);  // send to PC in binary mode(0-255) and display at hypertermianl screen
      }
   }   
}


pic 大哥,我是否有写错吗?
回复

使用道具 举报

发表于 24-11-2006 02:36 PM | 显示全部楼层
我原先没好好地想清楚, 只顾这需要用 10个 I/O pins。
所以采用了 PIC16F84A, 后来才发现 interface 的麻烦呢...
我刚刚才买了 877A, 打算下一次才用。

16F84A是13个I/O。
16F628A是16个I/O。
16F877A是33个I/O。
也可以买16F628A来玩。
877A你买多少钱?


#fuses HS,NOWDT,NOPROTECT
我是用 20MHz 的crystal 应该放 XT 还是放回 HS?
NOWDT = OFF WATHCHDOG TIMER, NOPROTECT = OFF PROTECTION
那么, POWER WRITE 该放 ENABLE 或 DISABLE 吗?

  1. Valid #fuse for 16F84A
  2. LP  Low power osc < 200 khz
  3. XT  Crystal osc <= 4mhz
  4. HS  High speed Osc (> 4mhz)
  5. RC  Resistor/Capacitor Osc with CLKOUT
  6. NOWDT  No Watch Dog Timer
  7. WDT  Watch Dog Timer
  8. NOPUT  No Power Up Timer
  9. PUT  Power Up Timer
  10. PROTECT Code protected from reads
  11. NOPROTECT Code not protected from reading
复制代码

1MHz ~4Mhz, 用XT。
20MHz 要用HS。
什么是POWER WRITE ?

#byte PortB =0x06
是指 PORT B 的 ADDRESS 是在 06H?

是的。PortA 的话是0x05 (看datasheet你就明白)

set_tris_b(0b00000000);// Setup portB as digital output
是指 PORT B 是 uC 的 output?
如果要放 uC 的 PORT B 是 input (从 ADC 来的 output), 是不是应该放
set_tris_b(0b11111111);
而 (0bXXXXXXXX)的 b 之前有个 0 代表什么呢?

对不起,是我搞错了,应该是:
set_tris_b(0b11111111);// Setup portB as digital input
0 代表output, 1 代表input。

pic 大哥,我是否有写错吗?  

只是改成HS, 不是XT.
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 26-11-2006 03:27 PM | 显示全部楼层

回复 #16 pic 的帖子

  1. 877A你买多少钱?
复制代码

877A = RM 24
84A = RM 10.50
MAX232N = RM 3.30
ADC 0804 = RM 10.60

  1. 什么是POWER WRITE ?
复制代码

对不起,是没有这个字的。
我其实是问 PWRT = PoWeR up Timer
是要放 disable 还是 enable 呢?

hyperterminal 没有显示想要的 reading.
我用scope查过了,PC 可以 send pulse 去 84A.
84A 也可以收到 ADC 和 PC 的 output.
但是 84A 没有传送 output 出来。
pic 大哥, 这是什么原因呢?
回复

使用道具 举报

发表于 26-11-2006 10:13 PM | 显示全部楼层
对不起,是没有这个字的。
我其实是问 PWRT = PoWeR up Timer
是要放 disable 还是 enable 呢?

没有PWRT的。。。
PoWeR up Timer? 是 PUT, 需要Enable。
  1.    #fuses   HS, NOPROTECT,NoWDT, PUT
复制代码

hyperterminal 没有显示想要的 reading.

hyperterminal 的setting对吗?9600 Baud rate 对吗?
可能你收到的是不能print 在screen 的字符(charater), 所以看不到。
请先改用:printf("%u",value);  // send to PC in ASCII mode(0-255)
如还不能收到,试以下的code:

  1. // CODE 1
  2. // Test if PIC can send data to PC
  3. #include <16F84A.h>
  4. #fuses HS,NOWDT,NOPROTECT,PUT
  5. #use delay(clock=20000000) // Use 20Mhz clock
  6. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) // Setup RS232, (Software USART)

  7. void main()
  8. {

  9.    while(1)
  10.     {
  11.         putc('A');  // Send a character 'A' to PC
  12.     }
  13. }
复制代码


  1. // CODE 2
  2. // Test if PIC can receive and send data to PC
  3. #include <16F84A.h>
  4. #fuses HS,NOWDT,NOPROTECT,PUT
  5. #use delay(clock=20000000) // Use 20Mhz clock
  6. #use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1) // Setup RS232, (Software USART)

  7. void main()
  8. {

  9.    while(1)
  10.     {
  11.         putc( getc()+1 );
  12.         // Echo on what you type, if type 'A', reply 'B'
  13.         // if type ‘1’, reply ‘2’
  14.     }
  15. }
复制代码


我用scope查过了,PC 可以 send pulse 去 84A.
84A 也可以收到 ADC 和 PC 的 output.
但是 84A 没有传送 output 出来。
pic 大哥, 这是什么原因呢?

你要确定hardware没接错, TX/ RX 没接错。

16F84A的TX (Pin_A0, Pin17) 接去PC的RX (pin2)
16F84A的RX (Pin_A1, Pin18) 接去PC的TX (pin3)
TX---->----RX
RX----<----TX


MAX232 有没接错?你可以把16F84A先拿掉,再把Pin 17 & Pin 18 短路。
在Hyperterminal 打字,看MAX232 会不会echo回你打的字。
如没有echo, 那MAX232就没接对。
如有echo, 请试Code 1 和Code2。

还是不可以的话, 请放你的电路上来看。
回复

使用道具 举报

 楼主| 发表于 28-11-2006 05:36 AM | 显示全部楼层

回复 #18 pic 的帖子

太好了! 电脑可以接受 16F84A 的 output 了。
只不过...不是很稳定。
过了大概不久(十多分钟左右), 16F84A 又不能传送 output 了。
不知道是什么原因?

pic 大哥,接下来要怎样用 visual basic 来向 16F84A 沟通呢?
回复

使用道具 举报

发表于 28-11-2006 11:32 PM | 显示全部楼层
太好了! 电脑可以接受 16F84A 的 output 了。
只不过...不是很稳定。
过了大概不久(十多分钟左右), 16F84A 又不能传送 output 了。
不知道是什么原因?

可以先知道之前为什么不可以吗?作了什么又可以?
可以分享过程吗?你的经验对其他网友会有参考价值。

接下来要怎样用 visual basic 来向 16F84A 沟通呢?

参考VB的Help (MSDN), 查MSComm,看他的example范例。

最基本的:
'----------------------------------------------------------
'设定COM Port
   ' Use COM1.
   MSComm1.CommPort = 1
   ' 9600 baud, no parity, 8 data, and 1 stop bit.
   MSComm1.Settings = "9600,N,8,1"
   ' Tell the control to read 1 byte buffer when Input
   ' is used.
   MSComm1.InputLen = 0
   ' Open the port.
   MSComm1.PortOpen = True
'----------------------------------------------------------
PC要送character,
    MSComm.output=word
e.g :MSComm.output="Q"
'----------------------------------------------------------
PC要收character,
   AdcValue = ASC(MSComm1.Input)
'----------------------------------------------------------


先试试看吧。。。直接给答案可能会害了你。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 15-6-2024 06:40 PM , Processed in 0.074982 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表