5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 2591|回复: 6
打印 上一主题 下一主题

有刷电调,有代码PIC16F873

[复制链接]
跳转到指定楼层
楼主
发表于 2006-11-29 09:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


/*
* Read the ADC on a 16F873.
*/

#include <pic.h>
#include "adc.h"
#include "delay.h"
char adc_read(unsigned char channel)
{
char result;
ADCON1 = 0x0E; // left justified, AN0 is the only analog input
ADCON0 = (channel << 3) + 0xC1;  // enable ADC, RC osc.
DelayUs(30); // delay 30usec so the channel change will stabilize
ADGO = 1;
while(ADGO); // wait for conversion complete
result = ADRESH;
return result;
}
---------------------------------------------------
/*
* Delay functions
* See delay.h for details
*
* Make sure this code is compiled with full optimization!!!
*/
#include "delay.h"
void
DelayMs(unsigned char cnt)
{
#if XTAL_FREQ <= 2MHZ
do {
  DelayUs(996);
} while(--cnt);
#endif
#if    XTAL_FREQ > 2MHZ
unsigned char i;
do {
  i = 4;
  do {
   DelayUs(250);
  } while(--i);
} while(--cnt);
#endif
}
----------------------------------------------------
/*
* Delay functions for HI-TECH C on the PIC
*
* Functions available:
*  DelayUs(x) Delay specified number of microseconds
*  DelayMs(x) Delay specified number of milliseconds
*
* Note that there are range limits: x must not exceed 255 - for xtal
* frequencies > 12MHz the range for DelayUs is even smaller.
* To use DelayUs it is only necessary to include this file; to use
* DelayMs you must include delay.c in your project.
*
*/
/* Set the crystal frequency in the CPP predefined symbols list in
HPDPIC, or on the PICC commmand line, e.g.
picc -DXTAL_FREQ=4MHZ

or
picc -DXTAL_FREQ=100KHZ

Note that this is the crystal frequency, the CPU clock is
divided by 4.
* MAKE SURE this code is compiled with full optimization!!!

*/
#ifndef XTAL_FREQ
#define XTAL_FREQ 4MHZ  /* Crystal frequency in MHz */
#endif
#define MHZ *1000L   /* number of kHz in a MHz */
#define KHZ *1   /* number of kHz in a kHz */
#if XTAL_FREQ >= 12MHZ
#define DelayUs(x) { unsigned char _dcnt; \
     _dcnt = (x)*((XTAL_FREQ)/(12MHZ)); \
     while(--_dcnt != 0) \
      continue; }
#else
#define DelayUs(x) { unsigned char _dcnt; \
     _dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \
     while(--_dcnt != 0) \
      continue; }
#endif
extern void DelayMs(unsigned char);
----------------------------------------------------------
/***************************************************/
/* Servo Tester main.c                             */
/*                                                 */
/***************************************************/
#include <pic.h>
#include "adc.h"
#include "servo.h"
#include "delay.h"
bit sweep;
bit stop;
#define low(a) (a & 0x00ff)
static void interrupt isr(void)
{
// determine the interrupt source
// first the INTCON register
if(RBIF && RBIE)   // Port B Change Interrupt
{
  RBIF = 0;
}
if(INTF && INTE)   // Port B.0 Interrupt for Idle Line Detection
{
  INTF = 0;
}
if(T0IF && T0IE)   // TMR0 Interrupt
{
  T0IF = 0;
}
// Done with INTCON, it must be the PIR1 register
if(TMR1IF && TMR1IE)  // check timer 1
{
  TMR1IF = 0;
  servoisr();
}
if(TMR2IF && TMR2IE)  // check timer 2
{
  TMR2IF = 0;
}
if(CCP1IF && CCP1IE)  // check the CCP module
{
  CCP1IF = 0;
  servoCCPisr();
}
if(SSPIF && SSPIE)
{
  SSPIF = 0;
}
if(TXIF && TXIE)   // TX Character Interrupt
{
}
if(RCIF && RCIE)   // RX Character Interrupt
{
}
if(ADIF && ADIE)   // check the ADC
{
}
}
#define SWEEP_BUTTON 0x10
#define STOP_BUTTON 0x08
char check_stop()
{
static char bounce = 0;
char ret;
if(PORTA & STOP_BUTTON)
  bounce = 0;
else
  bounce ++;

if(bounce >= 3)
{
  ret = 1;
  bounce = 3;
}
else
  ret = 0;
return ret;
}
char check_sweep()
{
static char bounce = 0;
char ret;
if(PORTA & SWEEP_BUTTON)
  bounce = 0;
else
  bounce ++;

if(bounce >= 3)
{
  ret = 1;
  bounce = 3;
}
else
  ret = 0;
return ret;
}
const char table[] = {0x01,0x03,0x07,0x0f,0x01f,0x3f,0x7f,0xff};
void main()
{
char v;
int pos;
char direction;
char o_sweep;

initServo();
TRISB = 0x00;
PORTB = 0x00;
TRISA = 0x19;
TRISC = 0x00;
GIE = 1; // enable interrupts
setServo(127);
direction = 0;
pos = 0;

while(1)
{
  v = check_sweep();
  if(v && !o_sweep)
  {
   sweep = !sweep;
  }
  o_sweep = v;
  if(check_stop())
  {
   stop = !stop;
  }
  if(stop)
  {
   GIE = 0;
   PORTC = 0;
  }
  if(!stop)
  {
   GIE = 1;
  }
  v = adc_read(0);
  
  if(sweep)
  {
   if(pos == 0)
    direction = 1;
   if(pos == 255)
    direction = 0;
   if(direction)
   {
    pos += (v/4) + 1;
    if(pos > 255)
     pos = 255;
   }
   else
   {
    pos -= (v/4)+1;
    if(pos < 0)
     pos = 0;
   }
   
   PORTB = table[low(pos)/32];
   setServo( low(pos) );
  }
  else
  {
   pos = v;
   PORTB = table[low(pos)/32];
   setServo(low(pos));
  }
  DelayMs(20);
}
}

/**********************************************************/
/* Servo Tester Servo Code                                */
/**********************************************************/
#include <pic.h>
#include "servo.h"
char servoLow;
char servoHigh;
/* servo system uses CCP and TMR1 */
/* TMR1 Overflow is set for 20msecs */
/* set TMR1 for prescale of 1/2 */
/* CCP is set for clear on match after servo command period */
#define crystal 20000000
#define clock (crystal/8)
#define TWNTYMSEC (65535 - (clock / 50))
#define TWOUSEC (clock / 500000)
#define NONEMSEC (TWOUSEC * 475)
#define ONEMSEC (TWOUSEC * 525)
#define high(a) (a >> 8)
#define low(a) (a & 0x00ff)
#define RC2 0x04
void initServo()
{
CCP1CON = 0;
TRISC = 0;
TMR1IF = 0;
CCP1IF = 0;
TMR1H = high(TWNTYMSEC);
TMR1L = low(TWNTYMSEC);
servoLow = low(TWNTYMSEC + NONEMSEC);
servoHigh =high(TWNTYMSEC + NONEMSEC);
CCPR1L = servoLow;
CCPR1H = servoHigh;
CCP1CON = 0x0A;
CCP1IF = 0;
T1CON = 0x11;
TRISC &= ~RC2;
PORTC &= ~RC2;
CCP1IE = 1;
TMR1IE = 1;
PEIE = 1;
}
void servoisr()
// Turn on PORTC
{
PORTC |= RC2; // set PORTC.2
TMR1H = high(TWNTYMSEC);
TMR1L = low(TWNTYMSEC);
}
void servoCCPisr()
// after the high pulse, update the compare registers for the next pulse
{
PORTC &= ~RC2;
CCPR1L = servoLow;
CCPR1H = servoHigh;
}
void setServo(char pos)
/* 0 to 255 */
{
unsigned int v;
v = pos * (ONEMSEC/255);
v += TWNTYMSEC + NONEMSEC;
servoLow = low(v);
servoHigh = high(v);
}
-----------------------------------------
/***************************************************/
/* Autopilot servo.h                               */
/*                                                 */
/***************************************************/
void servoisr();
/* TMR1 ISR for Servo control */
void servoCCPisr();
/* CCP ISR for servo update */
void initServo();
/* initialize the system for servo drive */
void setServo(char pos);
/* set the servo position between 0 and 255 */
/* 128 will center the servo */
---------------------------------------------
/*
* adc.h
*/
/*
* Read the adc on the specified channel - return result
*/
extern char adc_read(unsigned char channel);

欢迎继续阅读楼主其他信息

主题

  • 没有相关信息
  • 没有相关信息
  • 没有相关信息
沙发
发表于 2006-11-29 11:13 | 只看该作者

看不懂 这是什么电路 请LZ解释 谢谢

3
发表于 2006-11-29 11:15 | 只看该作者
不知道LZ这是双向的 还是单向  还有红线内的电路 看不懂 请LZ 解释一下 谢谢
4
发表于 2006-11-29 21:11 | 只看该作者
支持!
这个应该是单向带刹车的电调!
“依然爱我”问的红线内电路是一个降压DCDC电路,用来产生+5V电压。
5
发表于 2006-11-30 21:55 | 只看该作者
[quote]原帖由 喜乐蒂 于 2006-11-29 21:11 发表
支持!
这个应该是单向带刹车的电调!
“依然爱我”问的红线内电路是一个降压DCDC电路,用来产生+5V电压。
谢谢 这朋友的 解释  原来是杀车 电路  我看明白了
那 5V 稳压  电路 我 是知道的  因为我也是搞电器 维修的
6
发表于 2006-12-1 22:11 | 只看该作者
原帖由 喜乐蒂 于 2006-11-29 21:11 发表
支持!
这个应该是单向带刹车的电调!
“依然爱我”问的红线内电路是一个降压DCDC电路,用来产生+5V电压。


LM2940  是国半的低压差线性稳压电源,不是 DC/DC。
7
发表于 2007-9-9 02:19 | 只看该作者
:em17:
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

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