Thursday, October 30, 2008

Build Cross-Compiled gcc for ARM by myself

This work is done by studying Cross-Compiled Linux From Scratch - Embedded (Version SVN-0.0.1-20080109-arm) material, The steps of building cross compiled gcc for ARM:

[Adding the ARMDEV User]

$ su -
# groupadd armdev
# useradd -s /bin/bash -g armdev -m -k /dev/null armdev
# useradd -s /bin/bash -g wizign -m armdev
# passwd armdev
# chown -Rv armdev ${ARMDEV}


[Preparing a New Partition]

# export ARMDEV='/mnt/armdev'
# install -dv ${ARMDEV}
# mkdir /vdisk/arm_disk
# mkdir -pv ${ARMDEV}
# mount --bind /vdisk/arm_disk ${ARMDEV}

[Create source directory]
# mkdir -v ${ARMDEV}/sources
# chmod -v a+wt ${ARMDEV}/sources

[Check and download packages]

$ su - armdev

[]Binutils (2.18)
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2

[]Busybox (1.4.1)
$ wget http://busybox.net/downloads/busybox-1.4.1.tar.bz2

[]CLFS-Bootscripts (1.0-pre4)
$ wget http://cross-lfs.org/files/packages/embedded-0.0.1/clfs-embedded-bootscripts-1.0-pre4.tar.bz2

[]E2fsprogs (1.39)
$ wget http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.39.tar.gz

[]GCC (4.1.2)
$ wget http://ftp.gnu.org/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2

[]Iana-Etc (2.20)
$ wget http://www.sethwklein.net/projects/iana-etc/downloads/iana-etc-2.20.tar.bz2

[]Linux (2.6.20.1)
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.20.1.tar.bz2

[]Linux-Headers (2.6.20.1-02252007)
$ wget http://cross-lfs.org/files/packages/embedded-0.0.1/linux-headers-2.6.20.1-02252007.tar.bz2

[]uClibc (0.9.29)
$ wget http://www.uclibc.org/downloads/uClibc-0.9.29.tar.bz2

[]Zlib (1.2.3)
$ wget http://www.zlib.net/zlib-1.2.3.tar.gz

[Check and download patched]

[]Binutils Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/binutils-2.18-posix-1.patch

[]Binutils Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/binutils-2.17-posix-1.patch

[]Binutils uClibc Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/binutils-2.17-uclibc-1.patch

[]Busybox Fixes Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/busybox-1.8.2-fixes-1.patch

[]GCC Cross Search Paths Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-cross_search_paths-1.patch

[]GCC Posix Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-posix-1.patch

[]GCC uClibc Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/gcc-4.1.2-uclibc-1.patch

[]Zlib DESTDIR Patch
$ wget http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-embedded/patches/zlib-1.2.3-DESTDIR-1.patch

[Final Preparations]

[]Setting up the environment

$ cat > ~/.bash_profile << "EOF"
> exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash
> EOF

$ cat > ~/.bashrc << "EOF"
> set +h
> umask 022
> ARMDEV=/mnt/armdev
> LC_ALL=POSIX
> PATH=${ARMDEV}/cross-tools/bin:/bin:/usr/bin
> export ARMDEV LC_ALL PATH
> EOF

$ source ~/.bash_profile

[]Creating directories

$ mkdir -pv ${ARMDEV}/build
$ mkdir -pv ${ARMDEV}/{bin,boot,dev,{etc/,}opt,home,lib/{firmware,modules},mnt}
$ mkdir -pv ${ARMDEV}/{proc,media/{floppy,cdrom},sbin,srv,sys}
$ mkdir -pv ${ARMDEV}/var/{lock,log,mail,run,spool}
$ mkdir -pv ${ARMDEV}/var/{opt,cache,lib/{misc,locate},local}
$ install -dv -m 0750 ${ARMDEV}/root
$ install -dv -m 1777 ${ARMDEV}{/var,}/tmp
$ mkdir -pv ${ARMDEV}/usr/{,local/}{bin,include,lib,sbin,src}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/{doc,info,locale,man}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/{misc,terminfo,zoneinfo}
$ mkdir -pv ${ARMDEV}/usr/{,local/}share/man/man{1,2,3,4,5,6,7,8}
$ mkdir -pv ${ARMDEV}/cross-tools{,/bin}
$ for dir in ${ARMDEV}/usr{,/local}; do
> ln -sv share/{man,doc,info} ${dir}
> done


[]Creating the passwd, group, and log Files

$ ln -svf ../proc/mounts ${ARMDEV}/etc/mtab

$ cat > ${ARMDEV}/etc/passwd << "EOF"
> root::0:0:root:/root:/bin/ash
> bin:x:1:1:bin:/bin:/bin/false
> daemon:x:2:6:daemon:/sbin:/bin/false
> adm:x:3:16:adm:/var/adm:/bin/false
> lp:x:10:9:lp:/var/spool/lp:/bin/false
> mail:x:30:30:mail:/var/mail:/bin/false
> news:x:31:31:news:/var/spool/news:/bin/false
> uucp:x:32:32:uucp:/var/spool/uucp:/bin/false
> operator:x:50:0:operator:/root:/bin/ash
> postmaster:x:51:30:postmaster:/var/spool/mail:/bin/false
> nobody:x:65534:65534:nobody:/:/bin/false
> EOF


$ cat > ${ARMDEV}/etc/group << "EOF"
> root:x:0:
> bin:x:1:
> sys:x:2:
> kmem:x:3:
> tty:x:4:
> tape:x:5:
> daemon:x:6:
> floppy:x:7:
> disk:x:8:
> lp:x:9:
> dialout:x:10:
> audio:x:11:
> video:x:12:
> utmp:x:13:
> usb:x:14:
> cdrom:x:15:
> adm:x:16:root,adm,daemon
> console:x:17:
> cdrw:x:18:
> mail:x:30:mail
> news:x:31:news
> uucp:x:32:uucp
> users:x:100:
> nogroup:x:65533:
> nobody:x:65534:
> EOF


$ touch ${ARMDEV}/var/run/utmp ${ARMDEV}/var/log/{btmp,lastlog,wtmp}
$ chmod -v 664 ${ARMDEV}/var/run/utmp ${ARMDEV}/var/log/lastlog


[Constructing Cross-Compile Tools]

[]Build CFLAGS
$ echo "Build CFLAGS"
$ echo unset CFLAGS >> ~/.bashrc
$ echo unset CXXFLAGS >> ~/.bashrc

# Application Binary Interface (ABI) for the ARM Architecture
# ABI Variables
# Table 6.1. List of Build Variables
# ABI BUILD=Value
# ------------------------- --------------------------------
# 32-Bit MIPS -mabi=32
# 32-Bit All Others -m32
# N32 MIPS -mabi=n32
# 64-Bit MIPS -mabi=64
# 64-Bit All Others -m64
echo "ABI Variables"
export BUILD="-m32"

# Build Variables
# Table 6.2. Processor Type and Target Triplets
# Processor Target Triplet
# ---------------------------------------------- -----------------------------------------
# Generic arm, little endian arm-unknown-linux-uclibc
# Generic arm, version 5, little endian armv5l-unknown-linux-uclibc
# Generic arm, version 5, big endian armv5b-unknown-linux-uclibc

$ export ARM_HOST="$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")"
# Generic arm, little endian
$ export ARM_TARGET="arm-unknown-linux-uclibc"
$ echo export ARM_HOST=\""${ARM_HOST}\"" >> ~/.bashrc
$ echo export ARM_TARGET=\""${ARM_TARGET}\"" >> ~/.bashrc

[]Linux-Headers-2.6.20.1-02252007

$ mkdir ${ARMDEV}/build
$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/linux-headers-2.6.20.1-02252007.tar.bz2
$ install -dv ${ARMDEV}/usr/include
$ cp -av ${ARMDEV}/build/linux-headers-2.6.20.1/include/{asm-generic,linux,mtd,scsi,sound} ${ARMDEV}/usr/include
$ cp -av ${ARMDEV}/build/linux-headers-2.6.20.1/include/asm-arm ${ARMDEV}/usr/include/asm


[]Cross Binutils-2.17

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/binutils-2.17.tar.bz2
$ cd binutils-2.17
$ patch -Np1 -i ${ARMDEV}/sources/binutils-2.17-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/binutils-2.17-uclibc-1.patch
$ mkdir -v ../binutils-build
$ cd ../binutils-build
$ ../binutils-2.17/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --with-sysroot=${ARMDEV} --disable-nls --enable-shared --disable-multilib
$ make configure-host
$ make
$ make install
$ cp -v ../binutils-2.17/include/libiberty.h ${ARMDEV}/usr/include


[]uClibc-0.9.29

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/uClibc-0.9.29.tar.bz2
$ cd uClibc-0.9.29

$ cp extra/Configs/Config.arm extra/Configs/Config.arm.orig
$ sed -e "/default/s:OABI:EABI:" extra/Configs/Config.arm.orig > extra/Configs/Config.arm
$ cp Makefile{,.orig}
$ sed -e 's/$(LN) -fs/cp/g' Makefile.orig > Makefile
$ for file in `find libc/sysdeps/linux -name Makefile`; do
> cp $file{,.orig}
> sed -e 's/$(LN) -fs/cp/g' -e 's@../libc/@$(TOPDIR)libc/@g' $file.orig > $file
> done

$ make defconfig ARCH=arm
$ cp .config{,.orig}
$ sed -e "/^CROSS_COMPILER_PREFIX/s:=.*:=\"${ARM_TARGET}-\":" -e "/^KERNEL_HEADERS/s:=.*:=\"${ARMDEV}/usr/include\":" -e "/^SHARED_LIB_LOADER_PREFIX/s:=.*:=\"/lib\":" -e "/^DEVEL_PREFIX/s:=.*:=\"/usr\":" -e "/^RUNTIME_PREFIX/s:=.*:=\"/\":" .config.orig > .config

$ UCLIBC_OPTIONS="DO_C99_MATH UCLIBC_HAS_RPC UCLIBC_HAS_CTYPE_CHECKED UCLIBC_HAS_WCHAR UCLIBC_HAS_HEXADECIMAL_FLOATS LDSO_PRELOAD_FILE_SUPPORT UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE UCLIBC_HAS_PRINTF_M_SPEC UCLIBC_HAS_IPV6 UCLIBC_HAS_GLIBC_CUSTOM_PRINTF UCLIBC_USE_NETLINK UCLIBC_HAS_FTW"
$ for config in $UCLIBC_OPTIONS; do
> cp .config{,.orig}
> sed -e "s:# ${config} is not set:${config}=y:" .config.orig > .config
> done
$ UCLIBC_OPTIONS="UCLIBC_HAS_CTYPE_UNSAFE"
$ for config in $UCLIBC_OPTIONS; do
> cp .config{,.orig}
> sed -e "s:${config}=y:# ${config} is not set:" .config.orig > .config
> done
$ echo "UCLIBC_HAS_FULL_RPC=y" >> .config
$ echo "UCLIBC_HAS_REENTRANT_RPC=y" >> .config

# If your ARM system is Big Endian, you will need at add the following lines to your configuration:

$ echo "ARCH_ANY_ENDIAN=y" >> .config
$ echo "ARCH_BIG_ENDIAN=y" >> .config
$ echo "ARCH_WANTS_BIG_ENDIAN=y" >> .config

# If your ARM system is Little Endian, you will need at add the following lines to your configuration:

$ echo "ARCH_ANY_ENDIAN=y" >> .config
$ echo "ARCH_LITTLE_ENDIAN=y" >> .config
$ echo "ARCH_WANTS_LITTLE_ENDIAN=y" >> .config

$ make oldconfig
$ make headers
$ mkdir ${ARMDEV}/usr/include/bits
$ make PREFIX=${ARMDEV} install_headers

[]Cross GCC-4.1.2 - Static

$ cd ${ARMDEV}/build
$ tar -jxvf ${ARMDEV}/sources/gcc-4.1.2.tar.bz2
$ cd gcc-4.1.2
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-uclibc-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-cross_search_paths-1.patch
$ mkdir -v ../gcc-build
$ cd ../gcc-build
$ ../gcc-4.1.2/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --disable-multilib --with-sysroot=${ARMDEV} --without-headers --disable-nls --disable-shared --disable-threads --enable-languages=c
$ make all-gcc
$ make install-gcc


[]ToolChain Variables

$ export CC="${ARM_TARGET}-gcc"
$ export CXX="${ARM_TARGET}-g++"
$ export AR="${ARM_TARGET}-ar"
$ export AS="${ARM_TARGET}-as"
$ export LD="${ARM_TARGET}-ld"
$ export RANLIB="${ARM_TARGET}-ranlib"
$ export STRIP="${ARM_TARGET}-strip"


[]uClibc-0.9.29

$ cd ${ARMDEV}/build
$ cd uClibc-0.9.29

$ make CC="${CC}"
$ make PREFIX=${ARMDEV} install


[]Clear ToolChain Variables

$ unset CC
$ unset CXX
$ unset AR
$ unset AS
$ unset LD
$ unset RANLIB
$ unset STRIP

[]GCC-4.1.2 - Cross Compiler Final

$ cd ${ARMDEV}/build
$ rm -fr gcc-4.1.2
$ tar -jxvf ${ARMDEV}/sources/gcc-4.1.2.tar.bz2
$ cd gcc-4.1.2
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-posix-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-uclibc-1.patch
$ patch -Np1 -i ${ARMDEV}/sources/gcc-4.1.2-cross_search_paths-1.patch
$ rm -fr ../gcc-build
$ mkdir -v ../gcc-build
$ cd ../gcc-build
$ ../gcc-4.1.2/configure --prefix=${ARMDEV}/cross-tools --host=${ARM_HOST} --target=${ARM_TARGET} --disable-multilib --with-sysroot=${ARMDEV} --disable-nls --enable-shared --enable-languages=c,c++ --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-threads=posix
$ make
$ make install

Friday, October 10, 2008

Make MCU Board - Music Box Module


The music notes is defined by frequency variations,
reference wiki - music note and
C (musical note).

Generally, the calculation is based on A4 music note:
f = [2 ^ (n/12)] × 440 Hz

For easily doing calculation, here we use C-1 as the base level:
There are all 11 levels, each level has 12 music notes
n = (i x 12)(level) + j (jth note)
f = [2 ^ (n/12)] x 8.176 Hz

Calculate all music note's frequencies by python:
# calculate number array
musicNotes = []
for i in range(11):
 row = []
 for j in range(12):
   row.append(8.176 * (2**((i*12+j)*(1.0/12))))
 musicNotes.append(row)

# display frequency table
for i in range(11):
 musicNotes[i]

[8.1760000000000002, 8.6621702594815986, 9.1772497069774346, 9.7229573722622469, 10.301114503940484, 10.913650647694201, 11.562610085962426, 12.250158660543748, 12.978591000891997, 13.75033818222874, 14.567975839030828, 15.434232760971051]
[16.352, 17.324340518963197, 18.354499413954866, 19.445914744524494, 20.602229007880968, 21.827301295388398, 23.125220171924852, 24.500317321087497, 25.957182001783995, 27.50067636445748, 29.135951678061655, 30.868465521942102]
[32.704000000000001, 34.648681037926387, 36.708998827909731, 38.891829489048988, 41.204458015761929, 43.654602590776797, 46.250440343849704, 49.000634642174987, 51.914364003567989, 55.001352728914959, 58.271903356123303, 61.736931043884205]
[65.408000000000001, 69.297362075852774, 73.417997655819462, 77.783658978097975, 82.408916031523859, 87.309205181553594, 92.500880687699407, 98.001269284349974, 103.82872800713598, 110.00270545782992, 116.54380671224661, 123.47386208776841]
[130.816, 138.59472415170555, 146.8359953116389, 155.56731795619595, 164.81783206304772, 174.61841036310716, 185.00176137539881, 196.00253856869995, 207.6574560142719, 220.00541091565984, 233.08761342449321, 246.94772417553673]
[261.63200000000001, 277.1894483034111, 293.67199062327779, 311.1346359123919, 329.63566412609543, 349.23682072621432, 370.00352275079763, 392.00507713739989, 415.3149120285438, 440.01082183131967, 466.17522684898643, 493.89544835107347]
[523.26400000000001, 554.3788966068222, 587.34398124655559, 622.2692718247838, 659.27132825219087, 698.47364145242864, 740.00704550159526, 784.01015427479979, 830.6298240570876, 880.02164366263935, 932.35045369797285, 987.79089670214694]
[1046.528, 1108.7577932136444, 1174.6879624931112, 1244.5385436495676, 1318.5426565043817, 1396.9472829048573, 1480.0140910031905, 1568.0203085495996, 1661.2596481141752, 1760.0432873252787, 1864.7009073959457, 1975.5817934042939]
[2093.056, 2217.5155864272874, 2349.3759249862223, 2489.0770872991352, 2637.0853130087612, 2793.8945658097145, 2960.028182006381, 3136.0406170991969, 3322.5192962283504, 3520.0865746505574, 3729.4018147918891, 3951.1635868085878]
[4186.1120000000001, 4435.0311728545748, 4698.7518499724447, 4978.1541745982704, 5274.1706260175224, 5587.7891316194291, 5920.0563640127621, 6272.0812341983938, 6645.0385924567008, 7040.1731493011148, 7458.8036295837783, 7902.3271736171755]
[8372.2240000000002, 8870.0623457091497, 9397.5036999448894, 9956.3083491965408, 10548.341252035045, 11175.578263238858, 11840.112728025524, 12544.162468396788, 13290.077184913402, 14080.34629860223, 14917.607259167557, 15804.654347234351]

Base on above calculated values, we define const float gMusicNotes[11][12] , all the frequencies are recorded in the array.


The circuit schematic:















The main process:
(Depends on MCU's characters, for PIC16F877A , the compiler is PICC, the memory size of music_cell gSong[] is limited.)
(This program implements delay process, the deviation of sound frequency is obvious; replace by timer process, the sound frequency would be better than delay process)
/*******************************************************************************

  Copyright (c) 2008 Wizign Ltd.
  All Rights Reserved.

  main.c: Main program for demo trigger of speaker

  Version: 1.0.0

  Date: Oct 03, 2008

  Author: YenHung Chen

  E-mail: yhchen@wizign.com

  Revision:
  ---------- -----------------------------------------------------------------
  2008/10/03 Created by YenHung Chen, demo trigger of speaker for both 8051 and PIC

******************************************************************************/
/*******************************************************************************

<>For AT89S52

LCD display:
  There are 8 data pins, which are connected P2.
  The control pins are connected to P1_0, P1_1, and P1_2.

Speaker:
  P3_0


<>For PIC16F877A

LCD display:
  There are 8 data pins, which are connected PORTD
  The control pins are connected to RA0, RA1, and RA2.

Speaker:
  RC0


******************************************************************************/

#include "global.h"
#include "delay.h"
#include "lcd.h"
#include "timer.h"
#include "music.h"

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define IO and global variables

#ifdef MCU_PIC
/*
// Configurations
typedef unsigned int config;
config at 0x2007 __CONFIG = _XT_OSC & _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF;
*/
#endif

#ifdef MCU_PIC
bank1 static music_cell gSong[] = {
#else   // default is MCU_8051
music_cell gSong[] = {
#endif
  {C4, LA,    1}, {C4, LA, 0.25}, {C4, SO, 0.25}, {C4, LA,  0.5},
  {C4, SO,    1}, {C4, MI,    1}, {C4, SO,  0.5}, {C4, MI,  0.5},
  {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2}, {C4, MI,    0},
  {C4, RE,    1}, {C4, RE,  0.5}, {C4, DO,  0.5}, {C4, RE,  0.5},
  {C4, RE,  0.5}, {C4, SO,    1}, {C4, SO,  0.5}, {C4, MI,  0.5},
  {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2}, {C4, MI,    0},
  {C4, LA,    1}, {C4, LA,  0.5}, {C4, SO,  0.5}, {C4, LA,  0.5},
  {C4, SO,  0.5}, {C4, MI,    1}, {C4, FA,  0.5}, {C4, FA, 0.25},
  {C4, FA, 0.25}, {C4, MI,  0.5}, {C4, RE,  0.5}, {C4, MI,    2},
  {C4, MI,    0}, {C4, SO,    1}, {C4, SO,  0.5}, {C4, SO,  0.5},
  {C4, SO,  0.5}, {C4, SO,  0.5}, {C4, SI,    1}, {C4, LA,  0.5},
  {C4, LA, 0.25}, {C4, LA, 0.25}, {C4, LA,  0.5}, {C4, SO,  0.5},
  {C4, LA,    2}, {C4, LA,    0}, {C5, DO,    1}, {C5, DO,  0.5},
  {C5, DO,  0.5}, {C4, SI,    1}, {C4, SO,    1}, {C4, LA,  0.5},
  {C4, LA, 0.25}, {C4, LA, 0.25}, {C4, LA,  0.5}, {C4, SO,  0.5},
  {C4, LA,  1.5}, {C4, SO, 0.25}, {C4, MI, 0.25}, {C4, SO,    1},
  {C4, SO, 0.75}, {C4, SO, 0.25}, {C4, SO,  0.5}, {C4, SO,  0.5},
  {C4, SI,    1}, {C4, LA, 0.33}, {C4, LA, 0.33}, {C4, LA, 0.33},
  {C4, LA,  0.5}, {C4, SO,  0.5}, {C4, LA,    2}, {C4, LA,    0}
};

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define functions

/* Initilize parameters before run the main loop */
void InitParams(void)
{
  LCDInit();
  MusicInit();
}

/* Display message on LCD panel */
void DisplayMusicStatus(char* pMsg)
{
  LCDGoto(0);    // goto 1st line
  LCDPuts("  WIZIGN LTD.  ");

  // Display rotate status
  LCDGoto(0x40);    // goto 2nd line
  LCDPuts(pMsg);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// main program

void main(void)
{
  int count = 0;
  int direction = 0;  // 0:clockwise, 1:counter clockwise

  // Initilize parameters
  InitParams();

  /* do loop */
  while(1){
      DisplayMusicStatus("Play Music");
      MusicPlay(10, gSong);
  }
}

Wednesday, October 1, 2008

Make MCU Board - DC and Stepper Motor Module


DC motor and stepper motor are generally devices that they are used in automation control domain,
I introduce the control circuit and programming for these 2 type motors, as following:



The circuit schematic:














Main program:
/*******************************************************************************

Copyright (c) 2008 Wizign Ltd.
All Rights Reserved.

main.c: Main program for demo trigger of motors

Version: 1.0.0

Date: Oct 01, 2008

Author: YenHung Chen

E-mail: yhchen@wizign.com

Revision:
---------- -----------------------------------------------------------------
2008/10/01 Created by YenHung Chen, demo trigger of motors for both 8051 and PIC

******************************************************************************/
/*******************************************************************************



<>For AT89S52

LCD display:
There are 8 data pins, which are connected P2.
The control pins are connected to P1_0, P1_1, and P1_2.

Step motor:
P3_0, P3_1, P3_2, P3_3

DC motor:
P3_6, P3_7

<>For PIC16F877A

LCD display:
There are 8 data pins, which are connected PORTD
The control pins are connected to RA0, RA1, and RA2.

Step motor:
RC0, RC1, RC2, RC3

DC motor:
RC6, RC7


******************************************************************************/

#include "global.h"
#include "delay.h"
#include "lcd.h"
#include "motor.h"

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define IO and global variables

#ifdef MCU_PIC

// Configurations
typedef unsigned int config;
config at 0x2007 __CONFIG = _XT_OSC & _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF;

#endif


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// define functions

/* Initilize parameters before run the main loop */
void InitParams(void)
{

LCDInit();
MotorInit();
}

/* Display message on LCD panel */
void DisplayRotateStatus(char* pMsg)
{
LCDGoto(0);    // goto 1st line
LCDPuts("  WIZIGN LTD.  ");

// Display rotate status
LCDGoto(0x40);    // goto 2nd line
LCDPuts(pMsg);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// main program

void main(void)
{
int count = 0;
int direction = 0;  // 0:clockwise, 1:counter clockwise

// Initilize parameters
InitParams();

/* do loop */
while(1){
    if(direction == 0){
        DisplayRotateStatus("Clockwise");
        MotorStepRotate(MOTOR_ROTATE_CW, 4);
        MotorDCRotate(MOTOR_ROTATE_CW, 2);
    }else{  // left
        DisplayRotateStatus("C Clockwise");
        MotorStepRotate(MOTOR_ROTATE_CCW, 2);
        MotorDCRotate(MOTOR_ROTATE_CCW, 4);
    }
    count++;
    if(count >= 200){
        count = 0;
        direction = (direction == 0) ? 1 : 0;
    }
}
}